我正在处理一系列对象。每个对象都有两个属性,大小和数量。
var drives = [
{size:"900GB", count:3},
{size:"900GB", count:100},
{size:"1200GB", count:5},
{size:"900GB", count:1}
]
我不喜欢同样大小的多次出现,并希望将所有重复的大小合并到一个数组索引中。
首先,我按大小排序数组。然后我尝试制作一个for循环来管理重复。
drives.sort(function(obj1, obj2) {
var First = parseInt(obj1.size)
var Second = parseInt(obj2.size)
// Ascending: first size less than the previous
return First - Second;
})
for(var i = 0; i < drives.length-1; i++)
{
if(drives[i].size == drives[i+1].size)
{
drives[i+1].count+=drives[i].count;
//add the count of the first index to the second index's count
drives.splice(i, 1);
//delete the first index
}
}
https://jsbin.com/zayofiqoke/edit?js,console
for循环似乎没有正确迭代。它只结合了两个索引。我如何实现我正在寻找的东西?谢谢!
答案 0 :(得分:0)
您可以过滤数组并使用哈希表上的闭包更新相同大小的项目。
var drives = [{ size: "900GB", count: 3 }, { size: "900GB", count: 100 }, { size: "1200GB", count: 5 }, { size: "900GB", count: 1 }];
drives = drives.filter(function (hash) {
return function (a) {
if (!hash[a.size]) {
hash[a.size] = a;
return true;
}
hash[a.size].count += a.count;
};
}(Object.create(null)));
console.log(drives);
答案 1 :(得分:0)
这可能不是最好的实现,但你总是可以保留一个临时的元素列表并迭代它:
var tmp = {};
var out = [];
for(var i = 0; i < drives.length; i++) {
if(!tmp[JSON.stringify(drives[i])]) {
out.push(drives[i]);
tmp[JSON.stringify(drives[i])] = true;
}
}
我正在做的就是遍历数组,我将对象转换为JSON并将其用作对象中的键,因此如果有任何相同的对象,它们将被捕获,因为它们存在在临时对象中(保持查找~O(1)stringify会迭代遍历循环中的键。)
如果未定义密钥,请将对象推送到新阵列并继续到原始阵列的末尾。
所以你的最终解决方案在O(n)中运行,但它的内存效率并不高。
答案 2 :(得分:0)
修改:使用Array#filter
可能会更短。感谢Nina Scholz使用此策略发布第一个答案。我正在使用filter
函数的第二个参数,它设置给传递的回调的this
上下文,使用尽可能少的额外行。
var drives = [
{size:"900GB", count:3},
{size:"900GB", count:100},
{size:"1200GB", count:5},
{size:"900GB", count:1}
]
var result = drives.filter(function (e) {
if (e.size in this) this[e.size].count += e.count
else return this[e.size] = e
}, {})
console.log(result)
&#13;
<小时/> 原文:更好的方法可能是使用
Array#map
和Array#reduce
:
var drives = [
{size:"900GB", count:3},
{size:"900GB", count:100},
{size:"1200GB", count:5},
{size:"900GB", count:1}
]
var map = drives.reduce(function (map, e) {
if (e.size in map) map[e.size].count += e.count
else map[e.size] = e
return map
}, {})
var result = Object.keys(map).map(function (k) {
return this[k]
}, map)
console.log(result)
&#13;