admin管理员组

文章数量:1296481

I have an array of objects:

let objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}]

and I want to map the a and b properties to a single array:

[1, 2, 3, 4, 5, 6] //single array with a and b together

I could do this:

[...objArray.map(d => d.a), ...objArray.map(d => d.b)]

However I want to avoid looping through the objArray multiple times.

I have an array of objects:

let objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}]

and I want to map the a and b properties to a single array:

[1, 2, 3, 4, 5, 6] //single array with a and b together

I could do this:

[...objArray.map(d => d.a), ...objArray.map(d => d.b)]

However I want to avoid looping through the objArray multiple times.

Share asked Apr 17, 2017 at 15:47 haithamhaitham 3,5366 gold badges25 silver badges35 bronze badges
Add a ment  | 

7 Answers 7

Reset to default 3

You can map over the objArray to get the values, but then you end up with a nested array like so: [[1,2],[3,4],[5,6]]. Use apply to pass the nested arrays as attributes to concat to concatenate into a single array.

var objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6, c: 7}];
var reducedArray = [].concat.apply([], objArray.map(Object.values));
console.log(reducedArray);

Or with ES6, you can use the spread operator ... instead of passing an array of attributes to concat, and then you don't need to use apply, because the spread operator will spread out the nested arrays into individual properties.

const objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6, c: 7}];
const reducedArray = [].concat(...objArray.map(Object.values));
console.log(reducedArray);

Object.values will allow the map function to work on an arbitrary number of values. Thanks to Nina Scholz in this answer for the Object.values idea.

Note: both methods only work for arrays nested a single level deep.

let objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}];
var newArray = [];
objArray.forEach(function(obj) {
  newArray.push(obj.a, obj.b);
 });

You can use my favourite array iterator array.reduce().

It accepts an "Accumulator" value, and an iteration function that will be invoked for each item in the array. In the function you can amend the accumulator using the array item.

So for your case, you can make the accumulator an empty array [], and push the item's a and b properties...

var objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}];

var result = objArray.reduce(function(acc, obj) {
  acc.push(obj.a);
  acc.push(obj.b);

  return acc;
}, []);

or with ES6

var objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}];

var result = objArray.reduce((acc, { a, b }) => [ ...acc, a, b ]), []);

For more info see https://developer.mozilla/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

I would go with a reusable generator function as follows:

// Flatten objects to their values:
function* flatten(objects) {
  for (let obj of objects) yield* Object.values(obj);
}

// Example:
let objects = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}];
console.log([...flatten(objects)]);

Just for a variety;

var objArray = [{a: 1, b: 2}, {a: 3, b: 4, c: 7}, {a: 5, b: 6}],
    flatObj  = a => a.length ? Object.values(a[0]).concat(flatObj(a.slice(1))) : [];
console.log(flatObj(objArray));

You could use Array#concat, Array#map and Object.values for an arbitrary number of properties.

var objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, b: 6}],
    result = [].concat(...objArray.map(Object.values));
    
console.log(result);

I would follow danbahrami's code but potentially add a filter in the event that objects may not contain either a or b.

var objArray = [{a: 1, b: 2}, {a: 3, b: 4}, {a: 5, c: 6}];
var result = objArray.reduce((acc, { a, b }) => [ ...acc, a, b ], []).filter(i => i);
console.log(result)

本文标签: javascriptmap multiple properties in array of objects to the same arrayStack Overflow