If everything is lowercase it will be easier to compare.
Hint 2
Our strings might be easier to work with if they were arrays of characters.
Hint 3
A loop might help. Use indexOf() to check if the letter of the second word is on the first.
Solutions
Solution 1 (Click to Show/Hide)
Procedural
function mutation(arr) {
const test = arr[1].toLowerCase();
const target = arr[0].toLowerCase();
for (let i = 0; i < test.length; i++) {
if (target.indexOf(test[i]) < 0) return false;
}
return true;
}
Code Explanation
First we make the two strings in the array lowercase. test will hold what we are looking for in target.
Then we loop through our test characters and if any of them is not found we return false.
If they are all found, the loop will finish without returning anything and we get to return true.
Grab the second string, lowercase and turn it into an array; then make sure every one of its letters is a part of the lowercased first string.
Every will basically give you letter by letter to compare, which we do by using indexOf on the first string. indexOf will give you -1 if the current letter is missing. We check that not to be the case, for if this happens even once every will be false.
function mutation([ target, test ], i = 0) {
target = target.toLowerCase();
test = test.toLowerCase();
return i >= test.length
? true
: !target.includes(test[i])
? false
: mutation([ target, test ], i + 1);
}
Note that nesting ternaries this deeply is typically not recommended in professional code.
Solution 4 (Click to Show/Hide)
function mutation([elem1, elem2]) {
const regex = new RegExp(`[^${elem1}]`, 'i');
return !regex.test(elem2);
}
Code Explanation
Desconstruct the two elements of the array passed to the function and create a regular expression using the RegExp() constructor using a negated character set of all the first element’s characters. Adding the i flag makes the match case insensitive. The function returns the negated Boolean value of testing the regex with element two’s characters.
Here’s another solution. In terms of skill I’d say it’s beyond beginner but not quite intermediate.
function mutation(arr) {
arr.sort(function(a, b) {
return a.length - b.length;
});
for (var i = 0, len = arr[0].length; i < len; i++) {
if (arr[1].toLowerCase().indexOf(arr[0][i].toLowerCase()) < 0) {
return false;
}
}
return true;
}
This approach first sorts the two strings so that the string with the smallest length is in the first position. Then each character in the string with the smallest length (i.e., index 0) is tested against the characters in the string in the second position (i.e., index 1). If even one character is found not to match, the mutation function returns false. Otherwise mutation returns true. There’s also the necessary use of toLowerCase() to convert the strings to lowercase.
Here’s my solution. I resorted to adding booleans and checking if the sum matches the length of the second array element.
function mutation(arr) {
var word = arr[0].toLowerCase();
var letterToFind = arr[1].toLowerCase();
var correctLetters = 0;
for (var i = 0; i < letterToFind.length; i++) {
correctLetters += (word.indexOf(letterToFind[i]) != -1);
}
return (correctLetters === letterToFind.length);
}
mutation(["hello", "hey"]);
I like the approach, the only thing I would suggest is to iterate over arr[1] instead of arr[0] since we are only concerned about finding matches for the characters in arr[1], and instead of checking the indexOf of arr[1], check it for arr[0] to confirm all the matches. Everything else looks great!
btw what does the first part of your function do with sort? I’m not to great with functions within methods.
in freecodecamp “mutations”, one of the tests looks wrong “mutation([“Alien”, “line”]) should return true.” Can any one help me to know how it is true. Thank you
This is where I was headed. I wasn’t aware I could use arr[1][i] to look at each individual letter. For some reason I thought that indexOf would search the string for any number of combinations, but I was probably asking a bit much from the method. Thanks for the assist!
I ended up taking a round about way – initially tried converting the array to separate strings like the Basic Code Solution, but got stuck, so went back to keeping it as an array:
arr[0] = arr[0].toLowerCase();
arr[1] = arr[1].toLowerCase();
var result = [];
for (i=0; i<arr[1].length; i++) {
result[i] = arr[0].indexOf(arr[1][i]);
}
var resultArray = result.filter(function(val) {
return val===-1;
});
if (resultArray[0]===-1) {
return false;
}
return true;
}
I like this solution it is very similar to what I wanted to write but i do not understand why you put that “arr[1].length -1” why not just “arr[1].length”. I though I had understood for loops but these exercises have just shown me that what I learnt earlier does not even scratch the surface. when I see all these solutions, they seem to go againts everything i tought for loops should look like!! for loops are so complex and broad. I really dont like them. It seems like just when you think you get it, there is another BUT…
function mutation(arr) {
var a = arr[0].toLowerCase().split('');
var b = arr[1].toLowerCase().split('');
while (b.length) {
if (a.indexOf(b[0]) >= 0) {
b.splice(0, 1);
}
else if (a.indexOf(b[0]) < 0) {
return false;
}
}
return true;
}