Javascript 基于Key递归合并层次数据

Javascript Recursive Merge of Hierarchical Data Based on Key

我有一组数组:

sample = [
{
    'name' : 'alpha',
    'inner' : [
        {
            'name' : 'beta',
            'inner' : [
                {
                    'name' : 'gamma',
                    'inner' : [
                        {
                            'name' : 'one',
                            'inner' : []
                        }
                    ]
                }
            ]
        }
    ]
},
{
    'name' : 'alpha',
    'inner' : [
        {
            'name' : 'beta',
            'inner' : [
                {
                    'name' : 'gamma',
                    'inner' : [
                        {
                            'name' : 'two',
                            'inner' : []
                        }
                    ]
                }
            ]
        }
    ]
},
{
    'name' : 'epsilon',
    'inner' : [
        {
            'name' : 'one',
            'inner' : []
        }
    ]
},
{
    'name' : 'epsilon',
    'inner' : [
        {
            'name' : 'two',
            'inner' : []
        }
    ]
}
]

我想递归合并到这个:

sample = [
{
    'name' : 'alpha',
    'inner' : [
        {
            'name' : 'beta',
            'inner' : [
                {
                    'name' : 'gamma',
                    'inner' : [
                        {
                            'name' : 'one',
                            'inner' : []
                        },
                        {
                            'name' : 'two',
                            'inner' : []
                        }
                    ]
                }
            ]
        }
    ]
},
{
    'name' : 'epsilon',
    'inner' : [
        {
            'name' : 'one',
            'inner' : []
        },
        {
            'name' : 'two',
            'inner' : []
        }
    ]
}]

这是我目前的情况:

据我所知,它应该是这样工作的,这意味着有一个递归进入每个 "inner" 然后合并数组。

function _merge(arr) {
//
var result = [];
//
for (var i = 0; i < arr.length; i++) {
    var found = false;
    //
    for (var j = 0; j < result.length; j++) {
        //
        if ( result[j].name == arr[i].name) {
            found = true;
            //
            result[j].inner = result[j].inner.concat(arr[i].inner);
            //
            break;
        }
    }
    if (!found) {
        //
        result.push(arr[i]);
        //
    }
}
//
return result
//
}

//
function traverse(o ) {
    for (i in o) {
        if (!!o[i] && typeof(o[i])=="object") {
            //
            try{
                //
                build_array[i] = _merge(o[i])
                //
            }catch(e){
                //
                build_array = o[i]
                //
            }
            //
            traverse(o[i].inner );
        }
    }
}   
//

谢谢你的帮助

您可以使用迭代和递归方法来合并相同命名的对象。

var data = [{ name: 'alpha', inner: [{ name: 'beta', inner: [{ name: 'gamma', inner: [{ name: 'one', inner: [] }] }] }] }, { name: 'alpha', inner: [{ name: 'beta', inner: [{ name: 'gamma', inner: [{ name: 'two', inner: [] }] }] }] }, { name: 'epsilon', inner: [{ name: 'one', inner: [] }] }, { name: 'epsilon', inner: [{ name: 'two', inner: [] }] }],
    result = [];

data.forEach(function iter(r) {
    return function (a) {
        var o;
        if (!r.some(function (b) { if (a.name === b.name) { o = b; return true; } })) {
            r.push(a);
            return;
        }
        Array.isArray(a.inner) && a.inner.forEach(iter(o.inner = o.inner || []));
    };
}(result));

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

您可以添加其他属性

Object.keys(a).forEach(function (k) {
    if (['name', 'inner'].indexOf(k) === -1) {
        o[k] = a[k];
    }
});

迭代所有属性并仅分配不是 nameinner.

的键

var data = [{ name: 'alpha', data1: '1', inner: [{ name: 'beta', data2: '2', inner: [{ name: 'gamma', data3: '3', inner: [{ name: 'one', data4: '4', inner: [] }] }] }] }, { name: 'alpha', data5: '5', inner: [{ name: 'beta', data6: '6', inner: [{ name: 'gamma', data7: '7', inner: [{ name: 'two', data8: '8', inner: [] }] }] }] }, { name: 'epsilon', data9: '9', inner: [{ name: 'one', data10: '10', inner: [] }] }, { name: 'epsilon', data11: '11', inner: [{ name: 'two', data12: '12', inner: [] }] }],
    result = [];

data.forEach(function iter(r) {
    return function (a) {
        var o;
        if (!r.some(function (b) { if (a.name === b.name) { o = b; return true; } })) {
            r.push(a);
            return;
        }
        Object.keys(a).forEach(function (k) {
            if (['name', 'inner'].indexOf(k) === -1) {
                o[k] = a[k];
            }
        });
        Array.isArray(a.inner) && a.inner.forEach(iter(o.inner = o.inner || []));
    };
}(result));

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

这就是你想要的:

function merge(sourceArray,lastResult){

                    var output=lastResult || [];
                    sourceArray.forEach(function(sourceItem){

                        var founded=output.filter(function(item){
                            return item.name==sourceItem.name;
                        })[0];

                        if(!founded){
                            founded={
                                name:sourceItem.name,
                                inner:[]
                            };
                            output.push(founded);
                        }


                        founded.inner= merge(sourceItem.inner||[],founded.inner)
                    });
                    return output;
                }


                var source = [
                    {
                        'name' : 'alpha',
                        'inner' : [
                            {
                                'name' : 'beta',
                                'inner' : [
                                    {
                                        'name' : 'gamma',
                                        'inner' : [
                                            {
                                                'name' : 'one',
                                                'inner' : []
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        'name' : 'alpha',
                        'inner' : [
                            {
                                'name' : 'beta',
                                'inner' : [
                                    {
                                        'name' : 'gamma',
                                        'inner' : [
                                            {
                                                'name' : 'two',
                                                'inner' : []
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        'name' : 'epsilon',
                        'inner' : [
                            {
                                'name' : 'one',
                                'inner' : []
                            }
                        ]
                    },
                    {
                        'name' : 'epsilon',
                        'inner' : [
                            {
                                'name' : 'two',
                                'inner' : []
                            }
                        ]
                    }
                ];

                console.log(merge(source));