合并包含对象数组的对象

时间:2019-03-01 10:54:41

标签: javascript arrays object lodash

我有两个深度嵌套的对象,它们包含数组和这些数组中的对象。我想合并那些。使用“ lodash”无法识别数组中的对象。

我有这个:

var defaults = {
    rooms: [
        {
            name: 'livingroom',
            color: 'white'
        },
        {
            name: 'bedroom',
            color: 'red'
        }
    ],
    people: {
        clothes: [
            {
                fabric: 'wool',
                color: 'black'
            },
            {
                fabric: 'jeans',
                color: 'blue'
            }
        ]
    }
}

var specific = {
    people: {
        wigs: [
            {
                shape: 'trump'
            }
        ]
    },
    furniture : {
        foo: 'bar'
    }
}

结果应如下所示:

var merged = {
    rooms: [
        {
            name: 'livingroom',
            color: 'white'
        },
        {
            name: 'bedroom',
            color: 'red'
        }
    ],
    people: {
        clothes: [
            {
                fabric: 'wool',
                color: 'black'
            },
            {
                fabric: 'jeans',
                color: 'blue'
            }
        ],
        wigs: [
            {
                shape: 'trump'
            }
        ]
    },
    furniture : {
        foo: 'bar'
    }
}

使用lodash

const _ = require('lodash');
console.log(_.merge({}, specific, defaults));

我得到

{ people: { wigs: [ [Object] ], clothes: [ [Object], [Object] ] },
  furniture: { foo: 'bar' },
  rooms:
   [ { name: 'livingroom', color: 'white' },
     { name: 'bedroom', color: 'red' } ] }

这与:

Merge Array of Objects by Property using Lodash

How to merge two arrays in JavaScript and de-duplicate items

因为我没有通用的索引或名称,所以我有点迷茫。

1 个答案:

答案 0 :(得分:2)

您可以通过查看对象或数组将specific合并到defaults

function merge(a, b) {
    Object.keys(b).forEach(k => {
        if (!(k in a)) {
            a[k] = b[k];
            return;
        }
        if ([a, b].every(o => o[k] && typeof o[k] === 'object' && !Array.isArray(o[k]))) {
            merge(a[k], b[k]);
            return;
        }
        if (!Array.isArray(a[k])) a[k] = [a[k]];
        a[k] = a[k].concat(b[k]);
    });
    return a;
}

var defaults = { rooms: [{ name: 'livingroom', color: 'white' }, { name: 'bedroom', color: 'red' }], people: { clothes: [{ fabric: 'wool', color: 'black' }, { fabric: 'jeans', color: 'blue' }] } },
    specific = { people: { wigs: [{ shape: 'trump' }] }, furniture: { foo: 'bar' } };

[defaults, specific].reduce(merge);

console.log(defaults);
.as-console-wrapper { max-height: 100% !important; top: 0; }