遍历对象数组,如果它们具有相似的键则将它们合并
Loop Over Array of Objects and Combine them if they have similar keys
我正在尝试遍历类似于以下结构的数组,对于具有相同 ID 的每个对象,我希望将它们组合成一个对象,但包含所有 'names' 的数组与该 ID 关联。我的数组是按 id 预先排序的,我不能使用 JQuery,只能使用 vanilla JS。
转换为:
var array = [
{id=1, name = "Orange"},
{id=1, name = "Blue"},
{id=1, name = "Green"},
{id=2, name = "Blue"},
{id=3, name = "Orange"},
{id=3, name = "Blue"}
]
为此:
var newArray = [
{id=1, nameList = [Orange, Blue, Green]},
{id=2, nameList = [Blue]},
{id=3, namelist = [Orange, Blue]}
]
我试图通过将第一个对象与数组中的下一个对象进行比较,然后将第一个对象设置为第二个对象来做这样的事情,但被卡住了,因为 'secondObject' 实际上不是数组中的下一个对象。
for (var i in array) {
firstObject = array[i];
secondObject = array[i + 1];
if (firstObject.id === secondObject.id) {
firstObject['nameList'] = [firstObject.name + ',' + secondObject.name]
} else {
continue;
}
firstObject = secondObject;
}
我必须使用几千个 ID 来执行此操作,并且大多数 ID 都使用不同的名称重复,但有一些单个 ID 对象,例如 ID 2。
另一种方法是使用函数 reduce
var array = [ {id:1, name : "Orange"}, {id:1, name : "Blue"}, {id:1, name : "Green"}, {id:2, name : "Blue"}, {id:3, name : "Orange"}, {id:3, name : "Blue"}]
var result = Object.values(array.reduce((a, c) => {
(a[c.id] || (a[c.id] = {id: c.id, nameList: []})).nameList.push(c.name);
return a;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
如果您不必这样做in-place,您可以创建另一个对象并直接将东西放入其中。
var map = {}
for (var obj in array) {
var id = obj.id;
var name = obj.name;
if (!map[id]) {
map[id] = [];
}
map[id].push(name);
}
然后遍历地图以建立您的结果:
var result = [];
Object.keys(map).forEach(function(key) {
result.push[key, map[key]];
}
由于项目已排序,您可以检查结果数组中的最后一项,如果与实际项目不同,则生成一个新的结果对象。稍后推送 name
.
var array = [{ id: 1, name: "Orange" }, { id: 1, name: "Blue" }, { id: 1, name: "Green" }, { id: 2, name: "Blue" }, { id: 3, name: "Orange" }, { id: 3, name: "Blue" }],
grouped = array.reduce(function (r, { id, name }) {
if (!r.length || r[r.length - 1].id !== id) {
r.push({ id, namelist: [] });
}
r[r.length - 1].namelist.push(name);
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
我正在尝试遍历类似于以下结构的数组,对于具有相同 ID 的每个对象,我希望将它们组合成一个对象,但包含所有 'names' 的数组与该 ID 关联。我的数组是按 id 预先排序的,我不能使用 JQuery,只能使用 vanilla JS。
转换为:
var array = [
{id=1, name = "Orange"},
{id=1, name = "Blue"},
{id=1, name = "Green"},
{id=2, name = "Blue"},
{id=3, name = "Orange"},
{id=3, name = "Blue"}
]
为此:
var newArray = [
{id=1, nameList = [Orange, Blue, Green]},
{id=2, nameList = [Blue]},
{id=3, namelist = [Orange, Blue]}
]
我试图通过将第一个对象与数组中的下一个对象进行比较,然后将第一个对象设置为第二个对象来做这样的事情,但被卡住了,因为 'secondObject' 实际上不是数组中的下一个对象。
for (var i in array) {
firstObject = array[i];
secondObject = array[i + 1];
if (firstObject.id === secondObject.id) {
firstObject['nameList'] = [firstObject.name + ',' + secondObject.name]
} else {
continue;
}
firstObject = secondObject;
}
我必须使用几千个 ID 来执行此操作,并且大多数 ID 都使用不同的名称重复,但有一些单个 ID 对象,例如 ID 2。
另一种方法是使用函数 reduce
var array = [ {id:1, name : "Orange"}, {id:1, name : "Blue"}, {id:1, name : "Green"}, {id:2, name : "Blue"}, {id:3, name : "Orange"}, {id:3, name : "Blue"}]
var result = Object.values(array.reduce((a, c) => {
(a[c.id] || (a[c.id] = {id: c.id, nameList: []})).nameList.push(c.name);
return a;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
如果您不必这样做in-place,您可以创建另一个对象并直接将东西放入其中。
var map = {}
for (var obj in array) {
var id = obj.id;
var name = obj.name;
if (!map[id]) {
map[id] = [];
}
map[id].push(name);
}
然后遍历地图以建立您的结果:
var result = [];
Object.keys(map).forEach(function(key) {
result.push[key, map[key]];
}
由于项目已排序,您可以检查结果数组中的最后一项,如果与实际项目不同,则生成一个新的结果对象。稍后推送 name
.
var array = [{ id: 1, name: "Orange" }, { id: 1, name: "Blue" }, { id: 1, name: "Green" }, { id: 2, name: "Blue" }, { id: 3, name: "Orange" }, { id: 3, name: "Blue" }],
grouped = array.reduce(function (r, { id, name }) {
if (!r.length || r[r.length - 1].id !== id) {
r.push({ id, namelist: [] });
}
r[r.length - 1].namelist.push(name);
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }