我有一系列javascript对象,我想合并和分组。 这就是我输入的内容:
var input = [
{ // 0
A: { i: 0, j: 1 },
'A.k': { ki: 10, kj: 11 },
'A.k.l': { li: 20, lj: 21 }
},
{ // 1
A: { i: 0, j: 1 },
'A.k': { ki: 10, kj: 11 },
'A.k.l': { li: 22, lj: 23 }
},
{ // 2
A: { i: 0, j: 1 },
'A.k': { ki: 12, kj: 13 },
'A.k.l': { li: 24, lj: 25 }
},
{ // 3
A: { i: 0, j: 1 },
'A.k': { ki: 12, kj: 13 },
'A.k.l': { li: 26, lj: 27 }
},
{ // 4
A: { i: 2, j: 3 },
'A.k': { ki: 14, kj: 15 },
'A.k.l': { li: 28, lj: 29 }
},
{ // 5
A: { i: 2, j: 3 },
'A.k': { ki: 14, kj: 15 },
'A.k.l': { li: 30, lj: 31 }
},
{ // 6
A: { i: 2, j: 3 },
'A.k': { ki: 16, kj: 17 },
'A.k.l': { li: 32, lj: 33 }
},
{ // 7
A: { i: 2, j: 3 },
'A.k': { ki: 16, kj: 17 },
'A.k.l': { li: 34, lj: 35 }
}
];
我试图把它变成:
var output = [
{ i: 0, j: 1, k: [
{ ki: 10, kj: 11, l: [ { li: 20, lj: 21 }, { li: 22, lj: 23 } ] },
{ ki: 12, kj: 13, l: [ { li: 24, lj: 25 }, { li: 26, lj: 27 } ] }
]
},
{ i: 2, j: 3, k: [
{ ki: 14, kj: 15, l: [ { li: 28, lj: 29 }, { li: 30, lj: 31 } ] },
{ ki: 16, kj: 17, l: [ { li: 32, lj: 33 }, { li: 34, lj: 35 } ] }
]
}
];
我使用lodash,现在我的第一个想法是:
即使没有解决方案,也欢迎任何帮助。
答案 0 :(得分:0)
首先需要转换input
数组,因为您在所需的输出中没有A
proprety而某些项目是嵌套的
var intermediate = input.map(function (item) {
//restructure so that 'A.k' has name 'k' and is subitem,
//and 'A.k.l' is subitem of 'k' with name 'l'
return {
i: item.A.i,
j: item.A.j,
k: [{
kj: item['A.k'].kj,
ki: item['A.k'].ki,
l: [{
lj: item['A.k.l'].lj,
li: item['A.k.l'].li,
}]
}]
}
});
然后我们定义一个按给定键合并的函数(对象中的这些键应该是基本类型)。将重用此函数来合并多个级别
function merge(collection, keys) {
var result = _.groupBy(collection, function (item) {
// return a hash to group items. It won't be used to construct objects, just for grouping
// it must be a primitive type. will use string consisting of values
// dilimiter must be non-number and not empty to avoid false match of 1, 11 and 11, 1
return keys.map(function (key) {
return item[key]
}).join('-');
})
result = _.pairs(result)
.map(function (group) {
var list = group[1];
//list has items with fields names in [keys] equal
//merge all items with concatenatation of arrays
var res = _.reduce(list, function (a, b) {
return _.merge(a, b, function (prop1, prop2) {
if (_.isArray(prop1)) {
return prop1.concat(prop2);
}
});
});
return res;
});
return result;
}
//merge top level
var output = merge(intermediate, ['i', 'j']);
_.map(output, function (item) {
//merge children - in 'k'
item.k = merge(item.k, ['ki', 'kj']);
});
在action;
中查看答案 1 :(得分:0)
没有_的解决方案
var input = [{ // 0
'A': { i: 0, j: 1 },
'A.k': { ki: 10, kj: 11 },
'A.k.l': { li: 20, lj: 21 }
}, { // 1
A: { i: 0, j: 1 },
'A.k': { ki: 10, kj: 11 },
'A.k.l': { li: 22, lj: 23 }
}, { // 2
A: { i: 0, j: 1 },
'A.k': { ki: 12, kj: 13 },
'A.k.l': { li: 24, lj: 25 }
}, { // 3
A: { i: 0, j: 1 },
'A.k': { ki: 12, kj: 13 },
'A.k.l': { li: 26, lj: 27 }
}, { // 4
A: { i: 2, j: 3 },
'A.k': { ki: 14, kj: 15 },
'A.k.l': { li: 28, lj: 29 }
}, { // 5
A: { i: 2, j: 3 },
'A.k': { ki: 14, kj: 15 },
'A.k.l': { li: 30, lj: 31 }
}, { // 6
A: { i: 2, j: 3 },
'A.k': { ki: 16, kj: 17 },
'A.k.l': { li: 32, lj: 33 }
}, { // 7
A: { i: 2, j: 3 },
'A.k': { ki: 16, kj: 17 },
'A.k.l': { li: 34, lj: 35 }
}
];
var output = [];
function findIndex(a, o) {
var index;
a.some(function (el, n) {
var found = true, i;
for (i in o) {
found = found && el[i] === o[i];
}
return found ? (index = n, true) : false;
});
return index;
};
input.forEach(function (el) {
var i,
o = {},
k = {},
l = {},
index = findIndex(output, { i: el.A.i, j: el.A.j });
if (isFinite(index)) {
o = output[index];
} else {
o.i = el.A.i;
o.j = el.A.j;
o.k = [];
output.push(o);
}
index = findIndex(o.k, { ki: el['A.k'].ki, kj: el['A.k'].kj });
if (isFinite(index)) {
k = o.k[index];
} else {
k.ki = el['A.k'].ki;
k.kj = el['A.k'].kj;
k.l = [];
o.k.push(k);
}
for (i in el['A.k.l']) {
l[i] = el['A.k.l'][i];
}
k.l.push(l);
});
out(JSON.stringify(output, null, 4), true);
function out(s, pre) {
var descriptionNode = document.createElement('div');
if (pre) {
var preNode = document.createElement('pre');
preNode.innerHTML = s + '<br>';
descriptionNode.appendChild(preNode);
} else {
descriptionNode.innerHTML = s + '<br>';
}
document.getElementById('out').appendChild(descriptionNode);
}
<div id="out"></div>