0

I just tried tried solving a task on codewars.
The question is to write a function that reverse every word in a string that is greater than or equal to 5.

When I tried using forEach it doesn't change the element until I used map.

And according to MDN page,

forEach() does not mutate the array on which it is called. (However, callbackFn may do so)

So am expecting the array to mutate since I passed a callbackfn to it.

function spinWords(string){
 let a = string.split(" ");
//   console.log(a);
  a.forEach(el => {
    if (el.length >= 5) {
      let reverseSting = el.split("").reverse().join("");
      console.log(reverseSting);
      return reverseSting;
    }
    else {
//       
      return el;
    }
  })
  console.log(a);
  return a.join(" ");
}

function spinWords(string){
 let a = string.split(" ");
//   console.log(a);
  a = a.map(el => {
    if (el.length >= 5) {
      let reverseSting = el.split("").reverse().join("");
      console.log(reverseSting);
      return reverseSting;
    }
    else {
//       
      return el;
    }
  })
  console.log(a);
  return a.join(" ");
}
walexy
  • 609
  • 2
  • 7
  • 16
  • 3
    "*so am expecting the the array to mutate since i passed a callbackfn to it.*" why would you expect that? The callback functiopn doesn't cause any mutation. Nor does [a `return` in a `forEach` do anything at all](https://stackoverflow.com/questions/34653612/what-does-return-keyword-mean-inside-foreach-function) related to the array. – VLAZ Jul 23 '21 at 21:14
  • 2
    When it is suggested that a callback can mutate the array, it means nothing else than that the callback would explicitly assign a new value to an array entry. Returning a value has no meaning in a `forEach` callback. – trincot Jul 23 '21 at 21:15
  • @VLAZ So i can't mutate an array with a forEach – walexy Jul 23 '21 at 21:43
  • @lawalolawale not with a callback function that doesn't result in any mutation, no. – VLAZ Jul 23 '21 at 21:44
  • @VLAZ but i can use return in map to modify the element and store it in a new array right? – walexy Jul 23 '21 at 21:50
  • `return` doesn't *modify* anything. Mapping is the act of transforming one array to another in 1:1 relation described via a mapping function. The result of the function is an entry in the new array. Ideally, the mapping function doesn't mutate anything. – VLAZ Jul 23 '21 at 21:55
  • @VLAZ Thanks you very much..i really appreciate – walexy Jul 23 '21 at 23:10

1 Answers1

3

Neither function, map or forEach mutate the original array. The difference here is that map returns a new array while forEach doesn't. Which is why you have

a = a.map(el => {

You assign the array returned by the map back to the variable a. With a forEach the return values inside the callback are not used and there is no new array to work with.

const array = [1, 2, 3, 4, 5]
const square = number => number * number
// logs [1, 4, 9, 16, 25]
console.log(array.map(square))
// logs undefined
console.log(array.forEach(square))
Jakub Kotrs
  • 5,823
  • 1
  • 14
  • 30
  • To further demonstrate JaKub's point, please look here: https://i.stack.imgur.com/L8cSC.png For more info, take a look at the [forEach documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach). – Urmzd Jul 23 '21 at 21:21
  • 1
    I do not want to use the word never, because `arrayOfObjects.forEach(obj => { delete obj.prop })` kind of breaks the idea of "never", so the callback can mutate in a way. – Jakub Kotrs Jul 23 '21 at 21:23
  • @JakubMichálek Thanks alot.I really appreciate – walexy Jul 23 '21 at 21:48