我有一个对象数组(来自XLSX.js解析器,因此它的长度和内容各不相同)代表已经给予项目的授权。
简化,它看起来像这样:
var grants = [
{ id: "p_1", location: "loc_1", type: "A", funds: "5000" },
{ id: "p_2", location: "loc_2", type: "B", funds: "2000" },
{ id: "p_3", location: "loc_3", type: "C", funds: "500" },
{ id: "p_2", location: "_ibid", type: "D", funds: "1000" },
{ id: "p_2", location: "_ibid", type: "E", funds: "3000" }
];
我需要将这些合并到一个新的数组中,如下所示:
var projects = [
{ id: "p_1", location: "loc_1", type: "A", funds: "5000" },
{ id: "p_2", location: "loc_2", type: ["B", "D", "E"], funds: ["2000", "1000", "3000"] },
{ id: "p_3", location: "loc_3", type: "C", funds: "500" }
];
...这样当id
相同时,它会合并对象并合并其键值的某些(在示例type
和{{ 1}})成一个简单的子数组。这些合并对象中的其他键(funds
)继承第一个实例中的值,而忽略其余的值。
经过几次失败的尝试和大量的在线搜索后,我从this answer得到了一个想法,就像这样循环location
:
grants
它实际上工作得很好,除了我需要一个数组,我从末尾(从上面提到的答案)中删除var res = {};
$.each(grants, function (key, value) {
if (!res[value.id]) {
res[value.id] = value;
} else {
res[value.id].type = [res[value.id].type, value.type];
res[value.id].funds = [res[value.id].funds, value.funds];
}
});
var projects = []
projects = $.map( res, function (value) { return value; } );
,这反过来又创造了我似乎无法解决的问题现在。如果其中至少有三个项目,子数组会以某种方式嵌套在彼此中!我有点理解为什么(循环),但我想知道是否有办法将对象内的所有这些小多维数组转换为sigle数组(如:.join(',')
)?
type: ["B", "D", "E"]

var grants = [
{ id: "p_1", location: "loc_1", type: "A", funds: "5000" },
{ id: "p_2", location: "loc_2", type: "B", funds: "2000" },
{ id: "p_3", location: "loc_3", type: "C", funds: "500" },
{ id: "p_2", location: "_ibid", type: "D", funds: "1000" },
{ id: "p_2", location: "_ibid", type: "E", funds: "3000" }
];
var res = {};
$.each(grants, function (key, value) {
if (!res[value.id]) {
res[value.id] = value;
} else {
res[value.id].type = [res[value.id].type, value.type];
res[value.id].funds = [res[value.id].funds, value.funds];
}
});
var projects = []
projects = $.map( res, function (value) { return value; } );
$("pre").html(JSON.stringify(projects,null,2));

答案 0 :(得分:1)
你可以改变这些行:
res[value.id].type = [res[value.id].type, value.type];
res[value.id].funds = [res[value.id].funds, value.funds];
对此:
Array.isArray(res[value.id].type) ? res[value.id].type.push(value.type) : res[value.id].type = [res[value.id].type, value.type];
Array.isArray(res[value.id].funds) ? res[value.id].funds.push(value.funds) : res[value.id].funds = [res[value.id].funds, value.funds];
答案 1 :(得分:1)
我提出这个解决方案。
如果索引存在于项目数组中,它具有查找功能,如果是,则推送类型和资金,否则类型和资金属性将更改为数组,其值为第一个元素。
var grants = [
{ id: "p_1", location: "loc_1", type: "A", funds: "5000" },
{ id: "p_2", location: "loc_2", type: "B", funds: "2000" },
{ id: "p_3", location: "loc_3", type: "C", funds: "500" },
{ id: "p_2", location: "_ibid", type: "D", funds: "1000" },
{ id: "p_2", location: "_ibid", type: "E", funds: "3000" }
],
project = [];
grants.forEach(function (a) {
!project.some(function (b, i) {
if (a.id === b.id) {
project[i].type.push(a.type);
project[i].funds.push(a.funds);
return true;
}
}) && project.push({ id: a.id, location: a.location, type: [a.type], funds: [a.funds] });
});
document.write('<pre>' + JSON.stringify(project, 0, 4) + '</pre>');
答案 2 :(得分:1)
这会是一个想法吗?
var grants = [
{ id: "p_1", location: "loc_1", type: "A", funds: "5000" },
{ id: "p_2", location: "loc_2", type: "B", funds: "2000" },
{ id: "p_3", location: "loc_3", type: "C", funds: "500" },
{ id: "p_2", location: "_ibid", type: "D", funds: "1000" },
{ id: "p_2", location: "_ibid", type: "E", funds: "3000" }
];
var joined = [];
// map and push to joined
grants.map(
function (v) {
if (!(v.id in this)) {
this[v.id] = v;
joined.push(v);
} else {
var current = this[v.id];
current.type = [v.type].concat(current.type);
current.funds = [v.funds].concat(current.funds);
}
}, {}
);
// show it
document.querySelector('#result').textContent =
JSON.stringify(joined, null, ' ');
<pre id="result"></pre>
答案 3 :(得分:1)
这样做:
var tempArr = [];
var result = [];
for(i in grants){
var rowObj = grants[i];
var idPos = tempArr.indexOf(rowObj.id);
if(idPos > -1){
result[idPos].type.push(rowObj.type);
result[idPos].funds.push(rowObj.funds);
}else{
tempArr.push(rowObj.id);
rowObj.type = [rowObj.type]
rowObj.funds = [rowObj.funds]
result.push(rowObj);
}
}
console.log(result);