Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array.prototype.map() and Array.prototype.forEach()

Tags:

javascript

I've an array (example array below) -

a = [{"name":"age","value":31},
     {"name":"height (inches)","value":62},
     {"name":"location","value":"Boston, MA"},
     {"name":"gender","value":"male"}];

I want to iterate through this array of objects and produce a new Object (not specifically reduce).

I've these two approaches -

a = [{"name":"age","value":31},
     {"name":"height (inches)","value":62},
     {"name":"location","value":"Boston, MA"},
     {"name":"gender","value":"male"}];

// using Array.prototype.map()
b = a.map(function(item){
  var res = {}; 
  res[item.name] = item.value; 
  return res;
});
console.log(JSON.stringify(b));

var newObj = [];
// using Array.prototype.forEach()
a.forEach(function(d){
    var obj = {};
    obj[d.name] = d.value;
    newObj.push(obj)
});
console.log(JSON.stringify(newObj))

Is it not right to just use either one for this sort of operations? Also, I'd like to understand the use case scenarios where one will be preferred over the other? Or should I just stick to for-loop?

like image 809
Yellen Avatar asked Apr 28 '15 18:04

Yellen


1 Answers

As you've already discussed in the comments, there's no outright wrong answer here. Aside from some rather fine points of performance, this is a style question. The problem you are solving can be solved with a for loop, .forEach(), .reduce(), or .map().

I list them in that order deliberately, because each one of them could be re-implemented using anything earlier in the list. You can use .reduce() to duplicate .map(), for instance, but not the reverse.

In your particular case, unless micro-optimizations are vital to your domain, I'd make the decision on the basis of readability and code-maintenance. On that basis, .map() does specifically and precisely what you're after; someone reading your code will see it and know you're consuming an array to produce another array. You could accomplish that with .forEach() or .reduce(), but because those are capable of being used for more things, someone has to take that extra moment to understand what you ARE using them for. .map() is the call that's most expressive of your intent.

(Yes, that means in essence prioritizing efficiency-of-understanding over efficiency-of-execution. If the code isn't part of a performance bottleneck in a high-demand application, I think that's appropriate.)

You asked about scenarios where another might be preferred. In this case, .map() works because you're outputting an array, and your output array has the same length as your input array. (Again; that's what .map() does). If you wanted to output an array, but you might need to produce two (or zero) elements of output for a single element of input, .map() would be out and I'd probably use .reduce(). (Chaining .filter().map() would also be a possibility for the 'skip some input elements' case, and would be pretty legible)

If you wanted to split the contents of the input array into multiple output arrays, you could do that with .reduce() (by encapsulating all of them as properties of a single object), but .forEach() or the for loop would look more natural to me.

like image 85
S McCrohan Avatar answered Oct 18 '22 13:10

S McCrohan