Mutations(Spoiler: Solution)

Hi, @jvalonen! The thrill of solving a problem feels good, doesn’t it :smiley:?

Ok, let’s look at that code. The thing is that, there’s actually no need to convert the strings into arrays, because strings also have an include() function, and you can access characters like you do with arrays. You can remove the .split("") in arr1 = arr[0].toLowerCase().split("");, and your code will work fine (better, even). While you’re at it you can give arr1 and arr2 more descriptive names such as first and second, respectively.

CODE
function mutation(arr) {
  // create array for characters that are present in both strings
  var arr1_1 = [];

  // Store lowercase versions of the string inputs.
  var first = arr[0].toLowerCase();
  var second = arr[1].toLowerCase();
  
  for (var i = 0; i < second.length; i++) {
    // check if `first` includes each character from `second`
    if (first.includes(second[i])) {
      // if `second[i]` is found in `first` push it to a new array
      arr1_1.push(second[i]);
    }
  }
  
  // join arr1_1 into a string
  var strToCompare = arr1_1.join([separator = '']);
  // compare the new string to `second`
  if (second == strToCompare) {
    return true;
  }
  return false;
}

Next, this will definitely be a source of confusion:
var strToCompare = arr1_1.join([separator = '']);

Just .join(''); will do.

Finally, note this part:

if (second == strToCompare) {
  return true;
}
return false;

This is a fairly common occurrence in code. It says,

If the condition is true, return true. Else (if the condition is false), return false.

But wait, if this is the case, why not just return the boolean value of the condition itself?

return second == strToCompare;
Now we have this code:
function mutation(arr) {
  // create array for characters that are present in both strings.
  // I could give this a more meaningful name, but naming things is hard. :)
  var arr1_1 = [];

  // Store lowercase versions of the string inputs.
  var first = arr[0].toLowerCase();
  var second = arr[1].toLowerCase();
  
  for (var i = 0; i < second.length; i++) {
    // check if `first` includes each character from `second`
    if (first.includes(second[i])) {
      // if `second[i]` is found in `first` push it to a new array
      arr1_1.push(second[i]);
    }
  }
  
  // join arr1_1 into a string
  var strToCompare = arr1_1.join('');
  return second == strToCompare;
}

There you go. Good work :thumbsup: !

2 Likes

At first I tried to solve this with a regular expression (having pretty much zero experience with those). In my head it made sense to match two sets of characters that way… I quickly hit a brick wall though.

Can a RegEx ninja chime in on why it’s not a good idea to solve this problem that way? Or if it is, how would you do it?

Thanks! After stumbling around I got the same feeling (about “did match” vs “did any of these not match”). Good to see that confirmed, it teaches me something about regex and when to use it :slight_smile:

I ended up using a loop as well. Didn’t even come close to that regex solution!

@P1xt I think it’s possible to use Regular Expressions with a similar approach to the “did any of these not match”

function mutation(arr) {
  for (var i = 0; i < arr[1].length; i++){
    var pattern = arr[1][i];
    var re = new RegExp(pattern, "gi");
    if (!re.test(arr[0]))
      return false;
  }
 
  return true;
}

Although this solution looks very clumsy, it was very important and useful for me to solve this problem by myself and gain rich experience on how each method works (and how my brain works too). After I solved this problem I’ve found in this topic the best solution and study it carefully. I try to avoid all unnecessary steps in my code in future. Thanks to everybody in this topic!!!

function mutation(arr) {

var arr1 = arr.slice(0,1);
var arr2 = arr.splice(1);

var arrToString1 = arr1.toString(’’);
var arrToString2 = arr2.toString(’’);

arrToString1=arrToString1.toLowerCase();
arrToString2=arrToString2.toLowerCase();

arrToString1=arrToString1.split(’’);
arrToString2=arrToString2.split(’’);

arrToString1=arrToString1.sort(’’);
arrToString2=arrToString2.sort(’’);

var arr33 = arrToString1.join(’’);
var arr44 = arrToString2.join(’’);

for (var i=0; i<arr44.length; i++) {
if ( arr33.indexOf(arr44[i]) === -1)
{return false;}}

return true;}

mutation([“hello”,“yeh”]);

Lot of code there guys…
My solution is simple.

    function mutation(arr) {
     for (var i=0; i<arr[1].length; i++){
            if ((arr[0]).toLowerCase().indexOf((arr[1][i]).toLowerCase(), 0) == -1){
                return false;
            }
        }
        return true;
    }

    mutation(["hello", "hey"]);

Good try :thumbsup: I do not recommend your approach though.

A better solution:

function mutation(arr) {
	// Iterate through every character in the second string, to check if it is present in the first string
	for (var i=0; i<arr[1].length; i++) {
                // Convert all characters to lower case
		if ( arr[0].toLowerCase().indexOf(arr[1][i].toLowerCase()) == -1 ) {
			return false;
		}
	}
	return true;
}

mutation(["Mary", "Army"]);

I think the problem is your else statement is in for loop

Some really clean solutions!

Here is my, less clean, solution:


function mutation(arr) {
  var x = arr[0].toLowerCase();
  var y = arr[1].toLowerCase().split("");
  var matches = 0;
  for (var i = 0; i < y.length; i++){
  if (x.match(y[i])){
    matches++;
    }
  }
if (matches === y.length){
  return true;
}
  else return false;
}

mutation(["Hello", "heyn"]);

There are some beautiful and concise answers! :astonished: :thumbsup:

Here’s my rather convoluted solution — but with only things learned from earlier exercices. Does it make any sense doing this ?

function mutation(arr) {
  // Preparing the array so words like "Hello" become "helo",
  // and "VoOdoO" become "vodo".
  // in order to get unique letters, and get rid of duplicates
  var preparedArray = arr.map(function(val){
    return val
            .toLowerCase()
             .split('') // to process individual letters
              .reduce(function(result, current){
                 var len = result.length;
                 // rebuild the word with only unique letters
                 // if the current letter is already in our string, pass
                 // else append it to the word.
                 while (len){
                   if (result[len - 1] === current)
                     return result;
                   len--;
                 }
                 return result + current;
             }, "");
  });
  
  // Get minimum required letters by getting
  // the length of the shortest word in the array
  var letters = Math.min(preparedArray[0].length, preparedArray[1].length);
  
  // Comparing the letters in both words,
  // decrementing the minimum letter requirement
  for (var i = 0; i < preparedArray[0].length; i++){
    for (var j = 0; j < preparedArray[1].length; j++){
      if (preparedArray[0][i] === preparedArray[1][j])
        letters--;
    }
  }
  // If the minimum is reached, return "true"
  return letters === 0;
}

Who r u? how u practice?How u write this better code?I am new here and also new to coding ,that is why i am asking.My codes r not this clear and efficient as Yours.do u practice day and night.

Utilizing Array.prototype.every()

function mutation(arr) {
  var a = arr[0].toLowerCase().split('');
  var b = arr[1].toLowerCase().split('');
  return b.every(function (element) {
    return a.indexOf(element) > -1;
  });
}

Maybe I’m a bit more experienced than you :slight_smile:
I think first time my code was awful but 10 years of practice… and practice… and practice… (I’m java-dev) and now it’s much better I hope.
So, just learn and practice and you’ll manage, belive me.

Please put in ur comments :slight_smile: 

function mutation(arr) {
 for(var i=0;i<arr[1].length;i++){
   if(arr[0].toLowerCase().indexOf(arr[1].toLowerCase().charAt(i))==-1)
     return false;
 }
  return true;
 }

@bargaviumapathy - FYI, you can drop the charAt(i) part and just use the ith index of arr[1] as seen below

if(arr[0].toLowerCase().indexOf(arr[1][i].toLowerCase())==-1)

@rmdawson71 : Thanks :slight_smile: Will do !

My solution

function mutation(arr) {
for(var i = 0, len = arr[1].length; i < len; i++){
if(arr[0].toLowerCase().indexOf(arr[1].charAt(i).toLowerCase()) == -1){
return false;
}
}
return true;
}

open for comments

This is what I have written:

function mutation(arr) {

var firstElement = arr[0].toLowerCase().split("");
var secondElement = arr[1].toLowerCase().split("");

for (i = 0; i < secondElement.length; i++) {
if (firstElement.indexOf(secondElement[i]) == -1) {
return false;
}
}
return true;
}

mutation([“khellkO”, “kfh”]);

A post was split to a new topic: Mutations not returning correct value on one of the test cases

here’s mine:

const mutation = ([orig, mutant]) =>
  ((o, ms) => ms.every(m => o.includes(m)))
  (orig.toLowerCase(), mutant.toLowerCase().split(''))