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