Coder Perfect

Extract the value of a property as an array from an array of objects.

Problem

I have a JavaScript object array that looks like this:

objArray = [ { foo: 1, bar: 2}, { foo: 3, bar: 4}, { foo: 5, bar: 6} ];

I’d like to extract a field from each object and return an array with the values, for example, field foo would return array [1, 3, 5].

I can do it with this simple method:

function getFields(input, field) {
    var output = [];
    for (var i=0; i < input.length ; ++i)
        output.push(input[i][field]);
    return output;
}

var result = getFields(objArray, "foo"); // returns [ 1, 3, 5 ]

Is there a more elegant or idiomatic way to achieve this that eliminates the need for a bespoke utility function?

Note that the suggested replica explains how to turn a single object into an array.

Asked by hyde

Solution #1

Here’s a quicker way to get it done:

let result = objArray.map(a => a.foo);

OR

let result = objArray.map(({ foo }) => foo)

Array.prototype.map is another option ().

Answered by Jalasem

Solution #2

Yes, but it relies on a JavaScript ES5 feature. This means it won’t operate in Internet Explorer 8 or earlier.

var result = objArray.map(function(a) {return a.foo;});

For brevity, you can use an arrow function on ES6 compatible JS interpreters:

var result = objArray.map(a => a.foo);

Array.prototype.map documentation

Answered by Niet the Dark Absol

Solution #3

In terms of JS-only solutions, I’ve found that a simple indexed for loop, as inelegant as it may be, outperforms its counterparts.

A single property is extracted from a 100000 element array (via jsPerf)

For loops, it’s customary. 368 operations per second

var vals=[];
for(var i=0;i<testArray.length;i++){
   vals.push(testArray[i].val);
}

for..of loop in ES6 303 operations per second

var vals=[];
for(var item of testArray){
   vals.push(item.val); 
}

Array.prototype.map 19 Ops/sec

var vals = testArray.map(function(a) {return a.val;});

TL;DR.map() is sluggish, but you can use it if readability is more important to you than speed.

Edit #2: 6/2019 – jsPerf link no longer works, thus it’s been removed.

Answered by pscl

Solution #4

Check out the _.pluck() method in Lodash or the _.pluck() function in Underscore. In a single function call, both do exactly what you desire!

var result = _.pluck(objArray, 'foo');

Update: As of Lodash v4.0.0, _.pluck() has been deprecated in favor of _.map() in conjunction with something similar to Niet’s solution. In Underscore, _.pluck() is still available.

Update 2: As Mark points out in the comments, a new function was created somewhere between Lodash v4 and 4.3 that restores this capability. The shorthand function _.property() returns a function for retrieving the value of an object’s property.

In addition, _.map() now accepts a string as the second parameter, which is then sent to _.property() (). As a result, the next two lines are the same as the pre-Lodash 4 code sample above.

var result = _.map(objArray, 'foo');
var result = _.map(objArray, _.property('foo'));

You may also access sub-properties with _.property() and therefore _.map() by passing a dot-separated string or array:

var objArray = [
    {
        someProperty: { aNumber: 5 }
    },
    {
        someProperty: { aNumber: 2 }
    },
    {
        someProperty: { aNumber: 9 }
    }
];
var result = _.map(objArray, _.property('someProperty.aNumber'));
var result = _.map(objArray, _.property(['someProperty', 'aNumber']));

In the previous example, both _.map() calls will yield [5, 2, 9].

If you’re more interested in functional programming, check out Ramda’s R.pluck() function, which looks somewhat like this:

var result = R.pluck('foo')(objArray);  // or just R.pluck('foo', objArray)

Answered by tomb

Solution #5

For cross-browser assurance, it is preferable to utilize libraries such as lodash or underscore.

The following method in Lodash can be used to get the values of a property in an array.

_.map(objArray,"foo")

and in Underscore

_.pluck(objArray,"foo")

Both will return

[1, 2, 3]

Answered by Tejas Patel

Post is based on https://stackoverflow.com/questions/19590865/from-an-array-of-objects-extract-value-of-a-property-as-array