Find the longest common prefix from an array of strings - javascript

Consider this:
var longestCommonPrefix = function(strs) {
strs.forEach((item, index) => {
let splitArr = item.split('');
console.log('split array item is: ' + splitArr)
});
};
longestCommonPrefix(["flower","flow","flight"])
https://leetcode.com/problems/longest-common-prefix/
I need to compare these arrays to find the common prefix in them. So the output of this code at the ends needs to be:
common prefix is: "fl"
As of right now the output of the above code block is this
split array item is: f,l,o,w,e,r
split array item is: f,l,o,w
split array item is: f,l,i,g,h,t
I need to either
Loop by each character and array so the output is something like:
f,f,f,l,l,l,o,o,i,w,w,g,e,,h,r,,t
I tried to do this like this:
Looping Through an Array of Characters
You might want to take a look at the String's split method.
So I am already doing that, and my thought process is now this:
lets get our arrays, iterate over each character, and then make a new master array where we can count each instance of a letter appearing 3 times and print out that character, in order to get our common prefix.
So now that approach is this:
var longestCommonPrefix = function(strs) {
// establish the new array
// we need this for later, outside our loop so we can have a giant array to sort/look at/count
let charArray = [];
// loop through each array
strs.forEach((item, index) => {
// split the array by character
let splitArr = item.split('');
// test console log
console.log('split array item is: ' + splitArr)
// iterate over each character, and push it into a new array
splitArr.forEach((letter, index) => {
charArray.push(letter)
});
});
// log final array
console.log('FINAL ARRAY IS...: ' + charArray)
};
longestCommonPrefix(["flower","flow","flight"])
So we're getting closer because we're now here:
FINAL ARRAY IS...: f,l,o,w,e,r,f,l,o,w,f,l,i,g,h,t
But we're not quite there with what we want, f,f,f,l,l,l,o,o,i,w,w,g,e,,h,r,,t
We need to somehow sort the array by matching character, I think...?
When we do charArray.sort() we get this:
"FINAL ARRAY IS...: e,f,f,f,g,h,i,l,l,l,o,o,r,t,w,w"
Not quite...
Here are some SO answers based on my google search keyword "sort array by matching characters" that kind of talk about it but aren't quite relevant to my question
Javascript sort an array by matching to string
Sort an array of strings based on a character in the string
What keyword/search should I have used to find the results?
How can I sort this array from e,f,f,f,g,h,i,l,l,l,o,o,r,t,w,w to f,f,f,l,l,l,o,o,i,w,w,g,e,,h,r,,t ... ?

Here's a possible solution, needs to cover cases with an empty array but you get an idea.
While all letters at index c are the same I keep looping, otherwise I exit.
At the end I take c characters from the first word as it's the length of the common prefix.
function longestCommonPrefix(strs) {
var splits = strs.map((item) => item.split(''));
var c = 0;
var matches = true;
while (matches) {
var letter = splits[0][c];
if (letter != null) {
matches = splits.every(s => s[c] == letter);
if (matches)
c++;
} else matches = false;
}
var prefix = strs[0].slice(0, c);
console.log("The prefix is: " + prefix);
};
longestCommonPrefix(["flower", "flow", "flight"])

Related

Trouble understanding .indexOf in this code problem

I recently completed this Leetcode assessment for an open-book interview. Luckily I was able to Google for help, and passed the assessment. I'm having trouble understanding what exactly is happening on the line declared below. I'd love it if one of your smartypants could help me understand it better!
Thank you!
The problem:
Have the function NonrepeatingCharacter(str) take the str parameter being passed, which will contain only alphabetic characters and spaces, and return the first non-repeating character. For example: if str is "agettkgaeee" then your program should return k. The string will always contain at least one character and there will always be at least one non-repeating character.
Once your function is working, take the final output string and combine it with your ChallengeToken, both in reverse order and separated by a colon.
Your ChallengeToken: iuhocl0dab7
function SearchingChallenge(str) {
// global token variable
let token = "iuhocl0dab7"
// turn str into array with .split()
let arrayToken = token.split('')
// reverse token
let reverseArrayToken = arrayToken.reverse();
// loop over str
for (var i = 0; i < str.length; i++) {
// c returns each letter of the string we pass through
let c = str.charAt(i);
***--------------WHAT IS THIS LINE DOING?-------------***
if (str.indexOf(c) == i && str.indexOf(c, i + 1) == -1) {
// create variable, setting it to array with first repeating character in it
let arrayChar = c.split()
// push colon to array
arrayChar.push(':')
// push reversed token to array
arrayChar.push(reverseArrayToken)
// flatten array with .flat() as the nested array is only one level deep
let flattenedArray = arrayChar.flat()
// turns elements of array back to string
let joinedArray = flattenedArray.join('')
return joinedArray;
}
}
};
What I'd do is:
Reduce the string to an object, where the keys are the letters and the values are objects containing counts of occurrences and initial index in the string
Sort the .values() of that object in order of minimum count and minimum index
Use the first entry in the result of the sort to return the character
So something like
function firstUnique(str) {
const counts = Array.from(str).reduce((acc, c, i) => {
(acc[c] || (acc[c] = { c, count: 0, index: i })).count++;
return acc;
}, {});
return Object.values(counts).sort((c1, c2) =>
c1.count - c2.count || c1.index - c2.index
)[0].c;
}

Each letter once uppercase

javascript function which returns an array of string in such a way that it contains all possible upper-case letters of the input string one at a time sequentially.
uppercase("hello") ➞ ["Hello", "hEllo", "heLlo", "helLo", "hellO"]
what i have tried is
const helloCapital = (str) => {
let a = [];
for (let i in str) {
a.push(str[i].toUpperCase() + str.slice(1));
}
return a;
};
but it gives weird results
[ 'Hello', 'Eello', 'Lello', 'Lello', 'Oello' ]
This looks like a challenge for a course or challenges website.
If that is the case, it is really, really not cool to come here and ask for that answer.
But, since I'm already here, here it goes a working solution.
const capitals = s => Array.from(s,(_,i)=>s.slice(0,i)+_.toUpperCase()+s.slice(i+1))
UPDATE: Explaining the code
Array.from works on iterable objects, such as strings, Arrays and, ArrayLike objects for example.
It calls the function you pass as the first argument on each element of the iterable, in this case, the string.
The function receives 1 element of the iterable (the _) and the position of that element (the i)
So the function is returning a concatenation of 3 things:
* the substring of the original string from 0 to i
* the current element of the iterable, or current character, toUpperCase()
* the substring of the original string from i+1 to the end of the string.
Your logic is wrong, to work you need to concat the slice before letter with capitalized letter and with the slice after letter.
function capitalizeEachLetter (text) {
return Array.from(text, (letter, index) =>
text.slice(0, index) + letter.toUpperCase() + text.slice(index + 1)
);
}
use array array map,
var str = "hello";
var capitals = Array.from(str).map((e, i, ar) => {
let r = [...ar];
r[i] = ar[i].toUpperCase();
return r.join('');
});
console.log(capitals)

creating new values by index in JS looping/arrays

I have an array of values:
let myArray = [ 'Ifmanwas',
'meanttos',
'tayonthe',
'groundgo',
'dwouldha',
'vegivenu',
'sroots' ]
I want to print out a new value for each item in the array so that the first item is a collection of all the characters at the zero index, the second is a collection of all the characters at the 1 index position, ect...
So for instance, the output of the first array would be "Imtgdvs" (all the letters at ("0"), the second would be "fearwer" (all the letters at index "1") ect...
I am very lost on how to do this and have tried multiple different ways, any help is appreciated.
For this simple attempt I have created an array of all the letters for the first instance:
function convertToCode(box) {
let arr = [];
for (i = 0; i < box.length; i++) {
let counter = i;
let index = box[counter];
let letter = index.charAt(0);
arr.push(letter);
}
console.log(arr);
}
convertToCode(myArray)
Thanks
The main issue in your example is this: index.charAt(0);. This will always get the first character, whereas you need a nested loop.
You could use Array.map() in combination with Array.reduce(), like so:
let myArray = ['Ifmanwas','meanttos','tayonthe','groundgo','dwouldha','vegivenu','sroots'];
const result = Array.from(myArray[0]) //Create an array as long as our first string
.map((l,idx) => //Update each item in that array...
myArray.reduce((out,str) => str[idx] ? out+str[idx] : out, "") //to be a combination of all letters at index [idx] from original array
);
console.log(result);
Note that this uses the first string in the array to decide how many strings to make, as opposed to the longest string.

Adding Characters to the Begining of an Array that form words

When looking at set of characters I am trying to put each letter into a specifc order in an array. For Example: Given the Strings "cat" and "dog" I would want an array that contains [d,o,g,c,a,t], cat at the end of the array because it was read first.
Currently I have tried this:
However, when I try the code below assuming the strings are "cat" and "dog".
I get an array containing: [c,a,t,d,o,g]. Instead of push I have also tried .unshift but the array now reads: [g,o,d,t,a,c].
var chars = /^[a-z]$/;
var string = [];
function makeword(){
if(currentChar.match(chars)){
string.push(currentChar);
currentChar = getNextChar(); //Gets next Character in the String
makeword();
}
}
Is something like this possible in Javascript?
If I understood you correctly, you want to provide a list of strings, then have them show up in an array in reverse order, with each letter as an element of the array. The following function will do just that:
function makeWords() {
var arr = [];
for(var i = arguments.length - 1; i >=0; i--) {
arr.push(arguments[i]);
}
return arr.join('').split('');
}
so running makeWords('cat', 'dog') will result in ['d','o','g','c','a','t'].
It's a relatively simple code when a functional approach is used. The rest and spread operators are very handy both to collect the function arguments and to spread the characters of a word into an array.
var characterify = (...c) => c.reduceRight((a,b) => a.concat([...b]) ,[]);
document.write("<pre>" + JSON.stringify(characterify("cat","dog")) + "</pre>");

javascript object, concatenate duplicate keys while keeping multiple values

I have javascript objects that follow this pattern. Keys are to the left of the = sign, values to the right. The keys that are duplicates need to be concatenated to one key while keeping all the values.
var arrUnique = ['arTitle=randomword','arTitle=random','beTitle=rand1','bnTitle=whatever','caTitle=mango','caTitle=mangoes']
Becomes this string:
arTitle = ['randomword','random' ], beTitle = ['rand1'], bnTitle = ['whatever'], caTitle = ['mango','mangoes']
Here is where I am at so far. Create an object with all the keys using regex. Then create a regex construction which loops through each object in keys and pushes to x only when it matches more then 1.
var keys = (/\w{2}Title=/gi);
var x = [];
for (i = 0; i < arrUniqueCount; i++){
var regexp = new RegExp(keys[i], "gi");
var str2 = arrUniqueString.match(regexp).length;
if (str2 > 1){
x.push(regexp[i])}
}
alert("repeats: " + x);
Next I was thinking of using regex to replace and match etc to finally get my outcome. I am finding this stage difficult. Would anybody mind sharing a better way?
I would go the route of just sliptting at the '=' sign then adding them to an object based on the key at index position 0 of that split.
var arrUnique = ['arTitle=randomword', 'arTitle=random', 'beTitle=rand1', 'bnTitle=whatever', 'caTitle=mango', 'caTitle=mangoes'];
//object to collect the final result in
var result = {};
//go through each item and split on the equal
//this will create an array or arrays that contain your key/value
arrUnique.map(function(x) {
return x.split("=");
}).forEach(function(item) {
//if the key doesn;t yet exist in the object declare it as an empty array
if (!result[item[0]]) {
result[item[0]] = [];
}
//push the value onto this key
result[item[0]].push(item[1]);
});
console.log(result);

Categories