Javascript合并/减少相同的多维对象

Javascript合并/减少相同的多维对象,javascript,merge,lodash,javascript-objects,reduce,Javascript,Merge,Lodash,Javascript Objects,Reduce,基于我的问题:,我用样本数据打开了一个新问题 我想合并/减少以下内容: var array = [{ 'key1': { 'key11': 0, 'key12': 1 }, 'key2': 0, 'key3': { 'key31': [1, 2], 'key32': { 'key321': 3, 'key322': [1, 2] } }, 'key4': 'test' }, { 'key1':

基于我的问题:,我用样本数据打开了一个新问题

我想合并/减少以下内容:

var array = [{
  'key1': {
    'key11': 0,
    'key12': 1
  },
  'key2': 0,
  'key3': {
    'key31': [1, 2],
    'key32': {
        'key321': 3,
        'key322': [1, 2]
    }
  },
  'key4': 'test'
  }, {
  'key1': {
    'key11': 1,
    'key12': 9
  },
  'key2': 2,
  'key3': {
    'key31': [4, 3],
    'key32': {
        'key321': 6,
        'key322': [8, 9]
    }
  },
  'key4': 'test'
  }, {
  'key1': {
    'key11': 3,
    'key12': 4
  },
  'key2': 7,
  'key3': {
    'key31': [3, 2],
    'key32': {
        'key321': 6,
        'key322': [7, 8]
    }
  },
  'key4': 'test'
}];
为此:

{
  'key1': {
    'key11': [0, 1, 3],
    'key12': [1, 9, 4]
  },
  'key2': [0, 2, 7],
  'key3': {
    'key31': [[1, 2], [4, 3], [3, 2]],
    'key32': {
        'key321': [3, 6, 6],
        'key322': [[1, 2], [8, 9], [7, 8]]
    }
  },
  'key4': 'test'
}
@stasovlas with lodash中的reduce函数()看起来不错,但我需要深入研究对象

_.reduce(data, function(result, item) {
    var added = _.find(result, {
        key4: item.key4
    });
    if (_.isObject(added)) {
        //!! better to merge with new object and add result to array again to avoid mutable
        added = _.mergeWith(added, item, function(addedVal, itemVal, key) {
            if (key === 'key4') {
                return addedVal;
            }
            return _.concat(addedVal, itemVal);
        });
        return result;
    }
    return _.concat(result, item);
}, []);
[ { key1: [ [Object], [Object], [Object] ],
    key2: [ 0, 2, 7 ],
    key3: [ [Object], [Object], [Object] ],
    key4: 1 } ]
这里的结果是仅在对象的第1层中合并对象

_.reduce(data, function(result, item) {
    var added = _.find(result, {
        key4: item.key4
    });
    if (_.isObject(added)) {
        //!! better to merge with new object and add result to array again to avoid mutable
        added = _.mergeWith(added, item, function(addedVal, itemVal, key) {
            if (key === 'key4') {
                return addedVal;
            }
            return _.concat(addedVal, itemVal);
        });
        return result;
    }
    return _.concat(result, item);
}, []);
[ { key1: [ [Object], [Object], [Object] ],
    key2: [ 0, 2, 7 ],
    key3: [ [Object], [Object], [Object] ],
    key4: 1 } ]
我不知道如何得到我的结果。我想我必须迭代每个对象n次。n是对象的深度

_.reduce(data, function(result, item) {
    var added = _.find(result, {
        key4: item.key4
    });
    if (_.isObject(added)) {
        //!! better to merge with new object and add result to array again to avoid mutable
        added = _.mergeWith(added, item, function(addedVal, itemVal, key) {
            if (key === 'key4') {
                return addedVal;
            }
            return _.concat(addedVal, itemVal);
        });
        return result;
    }
    return _.concat(result, item);
}, []);
[ { key1: [ [Object], [Object], [Object] ],
    key2: [ 0, 2, 7 ],
    key3: [ [Object], [Object], [Object] ],
    key4: 1 } ]
这是正确的方法还是比我想象的容易


mok

您可以通过迭代源对象的条目来合并每个级别,并创建一个新对象或一个用于添加结果的数组。继续处理子对象

key4
获得特殊待遇

函数合并(目标、源){
var singleKey='key4';
Object.entries(source.forEach)([key,value])=>{
if(value&&typeof value==='object'&&&!Array.isArray(value)){
合并(目标[键]=目标[键]|{},值);
返回;
}
如果(键===单键){
目标[键]=值;
返回;
}
目标[键]=目标[键]| |[];
目标[键]。推送(值);
});
回报目标;
}
var数组=[{key1:{key11:0,key12:1},key2:0,key3:{key31:[1,2],key32:{key321:3,key322:[1,2]},key4:“test”},{key1:{key11:1,key12:9},key2:2,key3:{key31:[4,3],key32:{key321[7,8]},key4:“test”}],
result=array.reduce(merge,{});
console.log(结果);

.as console wrapper{max height:100%!important;top:0;}
我做了一些改进,它对于任何类型的问题都更灵活

function merge(target, source) {
    var fixedKeys = ['key1', 'key2', 'keyn'];

    Object.entries(source).forEach(([key, value]) => {
        if (value && value.toString() === '[object Object]') {
            merge(target[key] = target[key] || {}, value);
            return;
        }
        if (value && Array.isArray(value)) {
            merge(target[key] = target[key] || [], value);
            return;
        }
        if (fixedKeys.indexOf(key) !== -1) {
            target[key] = value;
            return;
        }
        target[key] = target[key] || [];
        target[key].push(value);
    });
    return target;
}
现在你可以合并/减少更深层次的值/数组/对象,不需要从JS数组转换为对象或其他形式,它与JSON.stringify兼容。你可以设置一个只出现一次的键数组


希望这不仅对我有帮助:)

键4有什么特别之处?为什么它不是一个内部有三个
'test'
的数组?哦,对不起,我从另一个数组复制了一个结果。但是我需要一个像“key4”这样的ID键“谢谢,我现在不能检查,但明天就可以。key必须是我的ID和字符串,相同的值也必须是一个数组。我将添加一个带有unix时间戳的key5。完成数组缩减后,我将使用它生成timeseries chartsomg,这正是我想要的。现在我试图理解您的代码。这里到底发生了什么:targett[key]=target[key]| |【】?是否:如果target[key]为空,则[]?这将检查
target[key]
是否错误,如
undefined
并分配空数组。数组(不管长度或值如何)是一个真实的值,因此不再使用默认值进行赋值。啊,我不知道我可以直接使用变量赋值的简短版本。谢谢你,这是艺术!!!如果我看到了…我认为…好吧,这是有意义的,但我决不会在我的脑子里把它押韵。太好了,你把我的答案作为你接受的答案,没有提到…a然后接受它。如果觉得被利用了。对不起,这不是我的本意。我应该把它作为一个评论发表吗?作为一个帖子,这很好。