将多维数组转换为单个数组(JavaScript)
我有一个对象数组(来自XLSX.js解析器,因此它的长度和内容各不相同),代表已授予项目的赠款。
I have an object array (coming from an XLSX.js parser, so its length and contents vary) representing grants that have been given to projects.
简化后,看起来像这样:
Simplified, it looks something like this:
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" }
];
我需要将它们合并成一个新的数组,如下所示:
I need to merge these into a new array that will look like this:
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
相同,它将合并对象并组合键值的 some (在示例中, type
和 funds
)转换为简单的子数组。这些合并对象中的其他键(位置
)从第一个实例继承值,而忽略其余实例。
... so that when the id
is the same, it will merge the objects and combine some of their key values (in the example type
and funds
) into a simple sub-array. The other keys (location
) in these merged objects inherit the values from the first instance and ignore the rest.
经过几次失败的尝试和大量的在线搜索之后,我从此答案中得到了一个主意,以遍历拨款
,像这样:
After several failed attempts and a lot of searching online, I got an idea from this answer to loop through grants
like this:
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; } );
它确实可以正常工作,除了需要数组时,我删除了 .join(',')
从头到尾(来自上面提到的答案),这反过来又造成了我现在似乎无法解决的问题。如果其中至少有三个项目,则子数组会相互嵌套!我有点理解为什么(循环),但是我想知道是否有一种方法可以将对象内部的所有这些小的多维数组转换为单行数组(例如: type:[ B, D, E]
)?
It actually works perfectly, EXCEPT that as I need an array, I removed .join(',')
from the ends (from the answer mentioned above), which in turn has created the problem I can't seem to solve now. The sub-arrays become nested in each other somehow if there is at least three items in them! I sort of understand why (the loop), but I wonder if there is a way to convert all these little multi-dimensional arrays inside the objects into sigle arrays (like: 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));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre id="json"></pre>
这是个好主意吗?
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>