Why we cannot assign values in the map method?

Tell us what’s happening:

Hello. So i solved the ‘Search and Replace’ challenge using a for loop, but i wanted to practise also the map method. So when i tried the map method in order to iterate each element of the array and check if it mathes the ‘before’ string, i tried to assign the ‘after’ value on the ‘item’ but in the end, outside the method the array remains the same as before.

When i used console.log(item); in the scope of the map method, the value was changed but outside it was not? Why?

  **Your code so far**

function myReplace(str, before, after) {
if(before[0]==before[0].toUpperCase()){
  after=after.replace(after[0],after[0].toUpperCase());
  
}else{
   after=after.replace(after[0],after[0].toLowerCase());
}

let arr = str.split(" ");

for(let i=0;i<arr.length;i++){
  if(arr[i].toLowerCase()==before.toLowerCase()){
    arr[i]=after;
  }
}

// arr.map(item=>{
//   if(item.toLowerCase()==before.toLowerCase()){
//     item=after;
//   }
// });

return arr.join(" ");
}

//myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
//myReplace("He is Sleeping on the couch", "Sleeping", "sitting");
myReplace("I think we should look up there", "up", "Down");
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36.

Challenge: Search and Replace

Link to the challenge:

Two things:

  • .map doesn’t change the array, it returns a new array. So in your current code, arr is still the same, unless you reassign it
  • within the body of map, you need to return something in each iteration - either item, or after
2 Likes

Got it. I did like this:

function myReplace(str, before, after) {
if(before[0]==before[0].toUpperCase()){
  after=after.replace(after[0],after[0].toUpperCase());
  
}else{
   after=after.replace(after[0],after[0].toLowerCase());
}

let arr = str.split(" ");

let arr2 = arr.map(item=>{
   if(item.toLowerCase()==before.toLowerCase()){
     return item=after;
   }
   return item;
 });

console.log(arr2);
return arr.join(" ");
}

//myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
//myReplace("He is Sleeping on the couch", "Sleeping", "sitting");
myReplace("I think we should look up there", "up", "Down");

It worked. Thanks!

map returns a new array with the return value of the function used as argument

so you are missing both catching the return value of the map method, and a return statement inside the callback function

1 Like

I agree with what has been said so far, but as a practical example:

const arr1 = [1, 2, 3];
const arr2 = arr1.map(num => num * 2);
console.log(arr1);
// [1, 2, 3]
console.log(arr2);
// [2, 4, 6]

// ***

const arr3 = [1, 2, 3];
const arr4 = arr3.map(num => num *= 2);
console.log(arr3);
// [1, 2, 3]
console.log(arr4);
// [2, 4, 6]

// ***

const arr5 = [1, 2, 3];
const arr6 = arr5.map(num => { num *= 2 });
console.log(arr5);
// [1, 2, 3]
console.log(arr6);
// [undefined, undefined, undefined]

// ***

const arr7 = [{ num: 1 }, { num: 2 }, { num: 3 }];
const arr8 = arr7.map(obj => obj.num *= 2);
console.log(arr7);
// [{ num: 3 }, { num: 4 }, { num: 6 }]
console.log(arr8);
// [2, 4, 6]

In the first example we are doing it the “correct” way. In the second, we are trying to change the passed in value (with the *= but failing - we don’t change anything in the original but because of the implicit return, it still maps. In the third example we are trying to change the passed in variable (and failing) but have forgot to return something so the map doesn’t work. In the last example we see that if the element is a reference type, we can change things inside that object. This is because map is passing in a reference.

1 Like