根据我的问题:https://stackoverflow.com/a/40661953/2392461,我用示例数据打开了一个新问题。
我要合并/减少这个:
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和lodash的reduce函数(https://stackoverflow.com/a/40668315/2392461)看起来不错,但我需要更深入地研究对象。
_.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);
}, []);
这里的结果是仅在对象的第1层中的合并对象。
[ { key1: [ [Object], [Object], [Object] ],
key2: [ 0, 2, 7 ],
key3: [ [Object], [Object], [Object] ],
key4: 1 } ]
我不知道如何获得结果。我认为我必须迭代每个对象n次。 n是物体的深度。
这是正确的方法还是比我想象的容易?
打招呼
答案 0 :(得分:1)
您可以通过迭代源对象的条目来合并每个级别,并创建一个新对象或一个数组以添加结果。继续处理子对象。
key4
得到特殊待遇。
function merge(target, source) {
var singleKey = 'key4';
Object.entries(source).forEach(([key, value]) => {
if (value && typeof value === 'object' && !Array.isArray(value)) {
merge(target[key] = target[key] || {}, value);
return;
}
if (key === singleKey) {
target[key] = value;
return;
}
target[key] = target[key] || [];
target[key].push(value);
});
return target;
}
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" }],
result = array.reduce(merge, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分: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兼容。您可以设置一个只能出现一次的键数组。
希望这不仅对我有帮助:)