所以我现在已经挣扎了几个小时。这就是我想要做的。
我有一个对象数组:
initArr = [
{id: 5, time: 100, download: true},
{id: 2, time: 50, download: false},
{id: 3, time: 1000, download: true},
{id: 5, time: 50, download: true},
{id: 5, time: 550, download: false},
{id: 2, time: 1500, download: true}
]
某些对象具有相同的id
,我想将它们合并在一起。
-但是合并时,我想将两个合并对象的time
值相加。
-如果两个合并对象之一具有download: false
,则合并对象应具有false
,否则为true
。
这是我到目前为止的内容(即使考虑下载密钥,我仍然没有开始):
const mergedArr= [];
initArr.map(obj => obj['id'])
.map((id, i, arr) => {
if (arr.indexOf(id) === i) {
mergedArr.push(initArr[i]);
} else {
const mergeIndex = mergedArr.map( x => x.id).indexOf(id);
mergedArr[mergeIndex].playTime +=initArr[arr.indexOf(id)].playTime;
}
return mergedArr
});
我很乐意输入或提示:)
答案 0 :(得分:2)
您可以reduce
阵列。创建一个累加器对象,每个id
作为键,合并的对象作为值。如果id
已经存在,请用当前对象更新time
和download
。否则,添加当前id
作为键,并设置当前对象的副本作为其值。然后使用Object.values()
从此累加器对象获取一个值数组。
const initArr = [
{ id: 5, time: 100, download: true },
{ id: 2, time: 50, download: false },
{ id: 3, time: 1000, download: true },
{ id: 5, time: 50, download: true },
{ id: 5, time: 550, download: false },
{ id: 2, time: 1500, download: true }
]
const merged = initArr.reduce((acc, o) => {
if (acc[o.id]) {
acc[o.id].time += o.time;
acc[o.id].download = acc[o.id].download && o.download;
} else
acc[o.id] = { ...o };
return acc;
}, {})
console.log(Object.values(merged))
答案 1 :(得分:1)
通过对象的id
将数组缩减为Map,然后使用Map.values()
和Array.from()
(或扩展为数组)转换回数组。 / p>
注意:在这种情况下,将Map用作累加器要比使用对象好,因为id
属性是数字属性。在ES6中,对象通常保持插入顺序,除非属性为数字。将具有数字属性键的对象转换为数组时,数字属性排在最前面,并按其值排序。另一方面,地图始终保持插入顺序。
const initArr = [
{id: 5, time: 100, download: true},
{id: 2, time: 50, download: false},
{id: 3, time: 1000, download: true},
{id: 5, time: 50, download: true},
{id: 5, time: 550, download: false},
{id: 2, time: 1500, download: true}
]
const result = Array.from(initArr.reduce((r, o) => {
if(!r.has(o.id)) r.set(o.id, { ...o });
else {
const current = r.get(o.id);
current.time += o.time;
current.download = current.download && o.download
}
return r;
}, new Map).values());
console.log(result);
答案 2 :(得分:1)
尝试一下,也支持下载选项
const arr = [
{id: 5, time: 100, download: true},
{id: 2, time: 50, download: false},
{id: 3, time: 1000, download: true},
{id: 5, time: 50, download: true},
{id: 5, time: 550, download: false},
{id: 2, time: 1500, download: true}
]
const result = arr.reduce((res, obj) => {
const found = res.find(t => t.id === obj.id);
if(found){
found.time += obj.time;
found.download = found.download && obj.download;
} else {
res.push(obj);
}
return res;
}, []);
console.log(result);
答案 3 :(得分:0)
您可以将reduce用于:
其他
const arr = [
{id: 5, time: 100, download: true},
{id: 2, time: 50, download: false},
{id: 3, time: 1000, download: true},
{id: 5, time: 50, download: true},
{id: 5, time: 550, download: false},
{id: 2, time: 1500, download: true}
]
console.log(arr.reduce((a, o) => {
const i = a.findIndex(({id}) => id === o.id)
i + 1 ? a[i].time += o.time : a.push(o)
return a
}, []))
答案 4 :(得分:0)
另一个reduce
解决方案:
const initArr = [
{id: 5, time: 100, download: true},
{id: 2, time: 50, download: false},
{id: 3, time: 1000, download: true},
{id: 5, time: 50, download: true},
{id: 5, time: 550, download: false},
{id: 2, time: 1500, download: true}
]
const merged = initArr.reduce((a,c) => {
const found = a.find(x => x.id === c.id);
if (found) {
found.time += c.time;
found.download = found.download && c.download;
return a;
}
return [...a, {...c}];
}, []);
console.log(merged);
答案 5 :(得分:0)
function manipulation(initArr){
var resultArray = [];
var arrMap = new Map();
var currIndex = 0;
initArr.forEach(function(item, index){
if(arrMap.has(item.id)){
var existingItem = resultArray[arrMap.get(item.id)];
existingItem.time = item.time+existingItem.time;
if(existingItem.download && !item.download){
existingItem.download = false;
}
}else{
arrMap.set(item.id, currIndex);
resultArray.push(item);
currIndex++;
}
})
return resultArray;
}