简体   繁体   English

合并两个深层数组

[英]Merge two deep arrays

So I've got two infinitely deep arrays as seen below. 因此,我有两个无限深的数组,如下所示。

const one = [
    {
        name: 'CRISPS',
        items: [
            {
                name: 'salty crisps',
                items: []
            }
        ]
    },
    {
        name: 'CHOCOLATE',
        items: [
            {
                name: 'full sized bars',
                items: []
            }
        ]
    }
]

const two = [
    {
        name: 'CRISPS',
        items: [
            {
                name: 'salty crisps',
                items: []
            }
        ]
    },
    {
        name: 'DRINKS',
        items: [
            {
                name: 'fizzy drinks',
                items: []
            }
        ]
    },
    {
        name: 'CHOCOLATE',
        items: [
            {
                name: 'small sized bars',
                items: []
            }
        ]
    }
]

I would like to be able to merge them so that I will get the outcome of 我希望能够合并它们,以便获得

const three = [
    {
        name: 'CRISPS',
        items: [
            {
                name: 'salty crisps',
                items: []
            }
        ]
    },
    {
        name: 'CHOCOLATE',
        items: [
            {
                name: 'full sized bars',
                items: []
            },
            {
                name: 'small sized bars',
                items: []
            }
        ]
    },
    {
        name: 'DRINKS',
        items: [
            {
                name: 'fizzy drinks',
                items: []
            }
        ]
    }
]

This merge will be the combination of the two arrays as well as only keeping the unique values of the items in the list. 这种合并将是两个数组的组合,并且只会在列表中保留项目的唯一值。

I have an inclining that I will need to create a custom recursive function to merge these two, however I was hoping that there might be a premade solution to do this. 我有一个倾向,我将需要创建一个自定义递归函数来合并这两个函数,但是我希望可以有一个预制的解决方案来做到这一点。

I've attempted with lodash's _.merge() However I was either using it wrong or it is not applicable. 我曾尝试使用lodash的_.merge()但是我使用的错误或不适用。

Edit For lodash I attempted the standard _.merge(one, two) however this tended to not merge deeply. 编辑对于lodash,我尝试了标准的_.merge(one, two)但是这种合并不会很深。 From there I've started looking at creating my own recursive method. 从那里开始,我开始研究创建自己的递归方法。

I've also updated the example to how how CHOCOLATE should merge. 我还更新了示例,说明如何合并CHOCOLATE

Thanks! 谢谢!

You're right, a recursive function is the way to go. 没错,递归函数是解决方法。 The idea is that we merge the lists at the top level, and if we find things to merge in one AND two , we recursively call merge on THEIR items: 我们的想法是,我们在顶层合并列表,如果发现要合并的对象为onetwo ,我们将递归地调用THEIR项上的merge:

 function merge(arr1, arr2) { let res = []; let arr2Index = arr2.reduce((acc, curr) => { acc[curr.name] = curr; return acc; }, {}); // add all elements from arr1 to res after merging them with their common element in arr2 arr1.forEach(i => { if (i.name in arr2Index) { i.items = merge(i.items, arr2Index[i.name].items); delete arr2Index[i.name]; } res.push(i); }); // add remaining objects from arr2 to res res.push(...Object.values(arr2Index)); return res; } // Test const one = [{ name: 'CRISPS', items: [{ name: 'salty crisps', items: [{ name: 'very salty crisps', items: [{ name: 'mega salty crisps', items: [] }] }] }] }, { name: 'CHOCOLATE', items: [{ name: 'full sized bars', items: [] }] } ]; const two = [{ name: 'CRISPS', items: [{ name: 'salty crisps', items: [{ name: 'very salty crisps', items: [{ name: 'hi', items: [{ name: 'somewhat salty crisps', items: [] }] }] }] }] }, { name: 'DRINKS', items: [{ name: 'fizzy drinks', items: [] }] } ]; console.log(merge(one, two)); 

Try this method using spread operator: 使用传播运算符尝试以下方法:

 const one = [ { name: 'CRISPS', items: [{ name: 'salty crisps',items: [] }] }, { name: 'CHOCOLATE', items: [{ name: 'full sized bars', items: [] }] } ] const two = [ { name: 'CRISPS', items: [{ name: 'salty crisps',items: [] }] }, { name: 'DRINKS', items: [{ name: 'fizzy drinks',items: [] }] } ] const merge = (p, ...arrs) => [...new Set([].concat(...arrs).map(a => JSON.stringify(a)))].map(a => JSON.parse(a)); const three = merge('name', one, two); console.log(three); 

thanks to this post: https://gist.github.com/yesvods/51af798dd1e7058625f4 感谢这篇文章: https : //gist.github.com/yesvods/51af798dd1e7058625f4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM