我有一个JavaScript对象数组,其结构如下:

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

我想从每个对象中提取一个字段,并获得一个包含值的数组,例如,字段foo将给出数组[1,3,5]。

我可以用这种简单的方法做到这一点:

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 ]

是否有更优雅或更惯用的方法来实现这一点,从而不需要自定义实用程序函数?


注意建议的重复,它介绍了如何将单个对象转换为数组。


当前回答

如果您希望ES6+中有多个值,以下操作将起作用

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

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

这是因为左边的{foo,baz}使用对象析构函数,而右边的箭头由于ES6的增强的对象文本而相当于{foo:foo,baz:baz}。

其他回答

查看Lodash的_.pulling()函数或Undercore的_.plus()函数。两者都可以在一个函数调用中实现您想要的功能!

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

更新:从Lodash v4.0.0起,_.pulling()已被删除,支持_.map(),并与Niet的答案类似。pickle()在Undercore中仍然可用。

更新2:正如Mark在评论中指出的,在Lodash v4和4.3之间的某个地方,添加了一个新功能,再次提供了该功能。property()是一个速记函数,它返回用于获取对象中属性值的函数。

此外,_.map()现在允许将字符串作为第二个参数传入,并将其传入_.property()。因此,以下两行相当于前面Lodash 4中的代码示例。

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

_.property()和_.map()也允许您提供点分隔的字符串或数组,以便访问子属性:

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']));

上述示例中的两个_.map()调用都将返回[5,2,9]。

如果您对函数式编程有更多了解,请查看Ramda的R.pulp()函数,它看起来像这样:

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

从对象数组中轻松提取多个财产:

let arrayOfObjects = [
  {id:1, name:'one', desc:'something'},
  {id:2, name:'two', desc:'something else'}
];

//below will extract just the id and name
let result = arrayOfObjects.map(({id, name}) => ({id, name}));

结果将是〔{id:1,名称:'one'},{id:2,名称:'two'}〕

根据需要在map函数中添加或删除财产

从对象数组中解构并获取特定属性:

const customerList = dealerUserData?.partyDetails.map(
  ({ partyId, custAccountId }) => ({
    partyId,
    custAccountId,
    customerId: dealerUserData?._id,
    userId: dealerUserData?.authUserID,
  }),
);

谈到纯JS的解决方案,我发现,尽管它可能很不优雅,但简单的索引for循环比它的替代方案更具性能。

从100000个元素数组中提取单个属性(通过jsPerf)

传统循环368操作/秒

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

ES6用于。。循环303操作/秒

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

Array.prototype.map 19操作/秒

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

TL;DR-.map()很慢,但如果您觉得可读性比性能更重要,可以使用它。

编辑#2:6/2019-jsPerf链接断开,已删除。

在ES6中,您可以执行以下操作:

const objArray = [{foo: 1, bar: 2}, {foo: 3, bar: 4}, {foo: 5, bar: 6}]
objArray.map(({ foo }) => foo)