-1

Just getting into functional programming with .forEach(), .map(), .reduce(), .filter()

var arr = [
   {name: 'John', cars: '2', railcard: 'yes', preferences: ['taxi', 'tram', 'walking']},
   {name: 'Mary', cars: '0', railcard: 'no', preferences: ['cyling', 'walking', 'taxi']},
   {name: 'Elon', cars: '100000', railcard: 'no', preferences: ['Falcon 9', 'self-driving', 'Hyper-loop']}
]; 

I'm attempting to capitalise the names using .forEach() , but I'm having difficulty applying any methods to the result.

var capitaliseName = function (x) {
  return x.toUpperCase();
};

var arrCapitals = arr.forEach(function(name) {
  return capitaliseName( arr.name );
});

The above result is returning empty. I could really use a bit of an explanation.

The output I'm expecting is:

var arr = [
   {name: 'JOHN', cars: '2', railcard: 'yes', preferences: ['taxi', 'tram', 'walking']},
   {name: 'MARY', cars: '0', railcard: 'no', preferences: ['cyling', 'walking', 'taxi']},
   {name: 'ELON', cars: '100000', railcard: 'no', preferences: ['Falcon 9', 'self-driving', 'Hyper-loop']}
]; 

I previously asked this question How do I replace a string with integers in a multi-dimensional array

Community
  • 1
  • 1
alanionita
  • 1,272
  • 1
  • 16
  • 34

3 Answers3

0

forEach() does not return anything. It loops through each value, but doesn't return. Also, inside the forEach(), what you call name is actually the whole object. Instead of arr.name, use name.name (better yet, rename name in your parameters to obj and do obj.name).

You have a couple of options. The easiest is that your arr will have the capitalized names already.

arr.forEach(function(obj) {
  obj.name = capitaliseName( obj.name );
});

console.log(arr); // has capitalized names

If you want to create a new array and not change the previous one, use map() instead of forEach() and return the whole object in each loop.

const arrCapitalized = arr.map(obj => Object.assign(obj, { name: capitalizeName(obj.name));
samanime
  • 25,408
  • 15
  • 90
  • 139
  • Thanks. Didn't look closely enough at his capitalize function. Updated. Thanks for pointing out `name` too. =) – samanime Apr 25 '17 at 20:51
  • Hey there, thanks for the solution, it did the trick. I actually assigned the forEach to a variable, but weirdly when logging that variable the output was 'undefined' whilst the original array was indeed transformed as needed. Any idea why? I'm guessing it's to do with how forEach works. – alanionita Apr 25 '17 at 21:03
  • Yeah. `forEach()` doesn't return anything, so it's return value is `undefined`. It's basically the same as a `for` loop, just in function form. The original array gets modified because you modify the objects in the array. They're the same objects, just updated, so you see the changes in `arr`. – samanime Apr 25 '17 at 21:04
0

You should switch to map function, because map return array and forEach not, and there is another problem in every iteration you have the whole object and you should use Object.assign to create another object with uppercase name

var arrCapitals = arr.map(function(obj) {
  return Object.assign({},obj, {
    name: obj.name.toUpperCase()
  })
});
Slawa Eremin
  • 5,264
  • 18
  • 28
0

Your code seems to be fine, except two cases:

  • Array#forEach doesn't return anything, in your particular case, I would suggest you to use Array#map instead. Hovewer, Array#forEach would be helpful if only you would like to modify the original array of objects.
  • In your arrCapitals function, the name argument passed inside the callback function stands for each name property from the arr variable. That's why you have to refer to it by name.name, while you are refering to the whole array, with arr.name.

var arr = [
   {name: 'John', cars: '2', railcard: 'yes', preferences: ['taxi', 'tram', 'walking']},
   {name: 'Mary', cars: '0', railcard: 'no', preferences: ['cyling', 'walking', 'taxi']},
   {name: 'Elon', cars: '100000', railcard: 'no', preferences: ['Falcon 9', 'self-driving', 'Hyper-loop']}
]; 

var capitaliseName = function (x) {
  return x.toUpperCase();
};

var arrCapitals = arr.map(function(name) {
  return capitaliseName( name.name );
});                //    ^^^ each single name element from each object inside arr array

console.log(arrCapitals);
kind user
  • 40,029
  • 7
  • 67
  • 77