如何合并对象数组中的对象?

时间:2018-10-11 13:24:55

标签: javascript arrays ecmascript-6 lodash

我正在寻找将所有对象合并到一个数组中的最佳解决方案

const arrayOfObjects = [
 {name: 'Fred', surname: 'Shultz'}, {name: 'Anne', surname: 'Example'}
];

我想实现:{name: ['Fred', 'Anne'], surname: ['Example', 'Shultz']}

该(es6)的最佳选择是什么?也许我可以使用lodash做类似的事情?我应该使用哪些助手?

12 个答案:

答案 0 :(得分:8)

您可以通过迭代条目并收集值来缩小数组,具体取决于键。

const
    array = [{ name: 'Fred', surname: 'Shultz' }, { name: 'Anne', surname: 'Example' }],
    result = array.reduce((r, o) => {
        Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || []).push(v));
        return r;
    }, Object.create(null));

console.log(result);

答案 1 :(得分:7)

lodash很容易

grouped = _.mapValues(arrayOfObjects[0], 
    (val, key) => _.map(arrayOfObjects, key))

纯es6

let grouped = {};

for (let obj of arrayOfObjects)
    for (let [key, val] of Object.entries(obj))
        grouped[key] = (grouped[key] || []).concat(val)

如果项与项之间的键不同,则可以使用类似的方式来收集它们:

grouped = _(arrayOfObjects)
    .flatMap(_.entries)
    .groupBy(0)
    .mapValues(x => _.map(x, 1))
    .value()

答案 2 :(得分:7)

您可以这样做:

const arrayOfObjects = [
  {name: 'Fred', surname: 'Shultz'}, {name: 'Anne', surname: 'Example'}
];

const result = {};
arrayOfObjects.forEach(item => {
  Object.keys(item).forEach(key => {
    if (!result[key]) {
      result[key] = [];
    }
    result[key].push(item[key]);
  });
});

console.log(result);

答案 3 :(得分:5)

您可以像这样使用lodash的mergeWith

const result = _.mergeWith({}, ...arrayOfObjects, (value, objValue) =>
    (value || []).concat(objValue)
);

示例:

const arrayOfObjects = [
    {name: 'Fred', surname: 'Shultz'}, {name: 'Anne', surname: 'Example'}
];

const result = _.mergeWith({}, ...arrayOfObjects, (value, objValue) =>
    (value || []).concat(objValue)
);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

答案 4 :(得分:3)

数组减少的捷径:

const arrayOfObjects = [
 {name: "name1", surname: "surname1"}, {name: 'Anne', surname: 'Example'}, {name: 'name3', surname: 'Example3'}
];
/*
{name: ['Fred', 'Anne'], surname: ['Example', 'Shultz']}
*/
var result = arrayOfObjects.reduce((obj,current)=>{
    (obj['name'] = obj['name']||[]).push(current.name);
    (obj['surname'] = obj['surname']||[]).push(current.surname);
    return obj;
},{});
console.log(result);

答案 5 :(得分:2)

这是lodash的方法

  _(input).flatMap(_.entries).groupBy(0).mapValues(v => _.map(v, 1)).value()

var input = [
 {name: 'Fred', surname: 'Shultz'}, {name: 'Anne', surname: 'Example'}
];

var res =   _(input).flatMap(_.entries).groupBy(0).mapValues(v => _.map(v, 1)).value()

console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

如果对象没有完全相同的键集,这将很重要

答案 6 :(得分:2)

如果在这两个道具上设置了arrayOfObjects,那么它就很简单:

const data = [{ name: 'Fred', surname: 'Shultz' }, { name: 'Anne', surname: 'Example' }]

const r = data.reduce((r,c) => 
   (r.name.push(c.name), r.surname.push(c.surname),r), {name:[], surname:[]})

console.log(r)

一个reduce,其中有一个{name:[], surname:[]}的累加器。

如果您需要更加通用,可以使用any set of objects

const data = [{
  name: 'Fred',
  surname: 'Shultz'
},{
  name: 'Anne',
  surname: 'Example'	
},{
  name: 'John',
  position: 'Dev' // <--- Notice different prop
}]

const result = data.reduce((r,c) => 
  (Object.keys(c).map(k => r[k] = [...r[k] || [], c[k]]), r), {})

console.log(result)

再来一次,reduceObject.keys就可以完成工作。

请注意,两种方法都利用ES6 arrow functionsarray destricturing,并且(对于第二种方法)通过将多个操作括在括号(op1,op2)中来组合多个操作

答案 7 :(得分:2)

不要让它变得比需要的复杂。

const arrayOfObjects = [
    {name: 'Fred', surname: 'Shultz'},
    {name: 'Anne', surname: 'Example'}
];

const result = {name:[], surname:[]};
for (const obj of arrayOfObjects)
    for (const prop in result)
        result[prop].push(obj[prop]);

我将假定您静态地知道结果应具有的属性名称-无论如何都无法真正动态地进行操作,因为对于空的输入数组而言,这将无法正常工作。

答案 8 :(得分:0)

以下方法应该起作用-使用一些ES6帮助器,但是密钥是{5}中的Array#reduce

const result = arrayOfObjects.reduce((acc, obj) => {
    for (let key in obj) {
        if (key in acc) {
            acc[key].push(obj[key]);
        }
        else {
            acc[key] = [obj[key]];
        }
    }
    return acc;
}, {});

答案 9 :(得分:0)

这是实现细节的一个完美体现,以相当容易理解和可读的方式编写。

https://codesandbox.io/s/r7x16j950n

const arrayOfObjects = [
  { name: "Fred", surname: "Shultz" },
  { name: "Anne", surname: "Example" }
];

let obj = {};

arrayOfObjects.forEach(row => {
  Object.keys(row).forEach(key => {
    obj[key] = !obj[key]
      ? [row[key]]
      : [...obj[key], row[key]];
  });
});

console.log(obj);

答案 10 :(得分:0)

没有任何图书馆

const mergeObjectInArray=(input)=>{
const myObj={};
Object.keys(input[0]).forEach(key=>myObj[key]=input.map(inp=>inp[key]));
return myObj;
}

答案 11 :(得分:0)

  

带有纯javascript

var myInput = [{ a: 1, b: 2, c: 3 }, { a: 2, b: 4, c: 6 }, { a: 7, b: 8, c: 9 }];
    var myArray = [];
    var myObject = {};
    function isArray(a){
        return Object.prototype.toString.call(a) === '[object Array]' ;
    }
    for (var i = 0; i < myInput.length; i++) {
        for (var key in myInput[i]) {
            if (myInput[i].hasOwnProperty(key)) {
                if (myArray.indexOf(key) === -1) {
                    myArray.push(key);
                    myObject[key] = myInput[i][key];
                } else {
                    if (myObject.hasOwnProperty(key)) {
                        newary = [];
                        if (isArray(myObject[key])) {
                            for (var i = 0; i < myObject[key].length; i++) {
                                newary.push(myObject[key][i]);
                            }
                        } else {
                            newary.push(myObject[key]);
                        }
                        newary.push(myInput[i][key]);
                        myObject[key] = newary;
                    }
                }
            }
        }
    }
    console.log(myObject);