我正在尝试从此json中删除重复的条目,但它仅返回一个我不知道我要去哪里的对象。
代码如下。
// exemplary array of objects (id 'NewLive' occurs twice)
var arr = [
{"jobcodeid":{"S":"Etc_new"}},
{"jobcodeid":{"S":"NewLive"}},
{"jobcodeid":{"S":"NewLiveVid"}},
{"jobcodeid":{"S":"New_Live"}},
{"jobcodeid":{"S":"New_Live_Vid"}},
{"jobcodeid":{"S":"Newest"}},
{"jobcodeid":{"S":"NewestLive"}},
{"jobcodeid":{"S":"NewestLiveVid"}},
{"jobcodeid":{"S":"Very_New_Vid"}},
{"jobcodeid":{"S":"Etc_new"}},
{"jobcodeid":{"S":"NewLive"}},
{"jobcodeid":{"S":"NewLiveVid"}},
{"jobcodeid":{"S":"New_Live"}},
{"jobcodeid":{"S":"New_Live_Vid"}},
{"jobcodeid":{"S":"Newest"}},
{"jobcodeid":{"S":"NewestLive"}},
{"jobcodeid":{"S":"NewestLiveVid"}},
{"jobcodeid":{"S":"Very_New_Vid"}}
],
obj = {}, new_arr = [];
// in the end the last unique object will be considered
arr.forEach(function(v){
obj[v['id']] = v;
console.log(JSON.stringify(new_arr));
});
new_arr = Object.keys(obj).map(function(id) { return obj[id]; });
console.log(JSON.stringify(new_arr));
我也在此附上codepen。
答案 0 :(得分:4)
您的代码返回单个元素的原因是因为您使用的是v['id']
,但是对象上没有id
属性,因此在整个循环中,您将obj[undefined]
设置为以上。
尽管在您的jsfiddle代码中,这看起来是正确的,但代码似乎可以正常工作。
如果有人遇到此问题以了解如何从JavaScript中的数组中删除重复项,请使用以下几种选择:
从本质上讲,这是您使用的解决方案,遍历数组,检查键是否已添加到结果数组,如果不存在,则将元素添加到结果中。
示例:
const result = [];
const knownIDs = new Set();
for (const item of input) {
if (!knownIDs.has(item.jobcodeid.S)) {
result.push(item);
knownIDs.add(item.jobcodeid.S);
}
}
要过滤重复项,可以将元素转换为键->值的Map
,然后再转换回数组。之所以可行,是因为密钥在Map
中是唯一的,并且重复项将自动消除。这种方法的主要优点是,由于代码的简单性,它将减少错误。
console.log(
Array.from(
new Map(
input.map(i => [i.jobcodeid.S, i])
).values()
)
)
另一种选择是使用Set
记录已知ID,使用filter
删除具有已知ID的项目。此方法的优点是,由于意图很明确,因此可能更易于阅读。而且,与转换为Map
并返回之前相比,此方法更有效。
const knownKeys = new Set();
console.log(
input.filter(i => {
if (!knownKeys.has(i.jobcodeid.S)) {
knownKeys.add(i.jobcodeid.S);
return true;
}
})
);
const input = [{"jobcodeid":{"S":"Etc_new"}},{"jobcodeid":{"S":"NewLive"}},{"jobcodeid":{"S":"NewLiveVid"}},{"jobcodeid":{"S":"New_Live"}},{"jobcodeid":{"S":"New_Live_Vid"}},{"jobcodeid":{"S":"Newest"}},{"jobcodeid":{"S":"NewestLive"}},{"jobcodeid":{"S":"NewestLiveVid"}},{"jobcodeid":{"S":"Very_New_Vid"}},{"jobcodeid":{"S":"Etc_new"}},{"jobcodeid":{"S":"NewLive"}},{"jobcodeid":{"S":"NewLiveVid"}},{"jobcodeid":{"S":"New_Live"}},{"jobcodeid":{"S":"New_Live_Vid"}},{"jobcodeid":{"S":"Newest"}},{"jobcodeid":{"S":"NewestLive"}},{"jobcodeid":{"S":"NewestLiveVid"}},{"jobcodeid":{"S":"Very_New_Vid"}}];
// Classic for loop
const result = [];
const knownIDs = new Set();
for (const item of input) {
if (!knownIDs.has(item.jobcodeid.S)) {
result.push(item);
knownIDs.add(item.jobcodeid.S);
}
}
console.log(result.map(r => r.jobcodeid.S));
// To Map and back
console.log(
Array.from(
new Map(
input.map(i => [i.jobcodeid.S, i])
).values()
)
)
// filter and set
const knownKeys = new Set();
console.log(
input.filter(i => {
if (!knownKeys.has(i.jobcodeid.S)) {
knownKeys.add(i.jobcodeid.S);
return true;
}
})
);
为便于记录,我对Jacques' answer上可接受的解决方案,我的产品和性能改进进行了基准测试
accepted solution x 1,892,585 ops/sec ±3.48% (89 runs sampled)
Map and back x 495,116 ops/sec ±2.27% (90 runs sampled)
Set and filter x 1,600,833 ops/sec ±1.98% (90 runs sampled)
Jacques x 2,110,510 ops/sec ±0.98% (92 runs sampled)
Fastest is Jacques
如您所见,Jacques' solution的确是两倍的速度,因此,如果您打算过滤大型数组或性能很关键,则绝对应该选择它!
答案 1 :(得分:1)
首先,您必须使用obj[v['jobcodeid']] = v;
而不是obj[v['id']] = v;
。
但是由于v[jobcodeid]
是一个对象,因此js会将其转换为字符串,即[object Object]
,并且最终数组中将只有一个元素。
// exemplary array of objects (id 'NewLive' occurs twice)
var arr=[{"jobcodeid":{"S":"Etc_new"}},{"jobcodeid":{"S":"NewLive"}},{"jobcodeid":{"S":"NewLiveVid"}},{"jobcodeid":{"S":"New_Live"}},{"jobcodeid":{"S":"New_Live_Vid"}},{"jobcodeid":{"S":"Newest"}},{"jobcodeid":{"S":"NewestLive"}},{"jobcodeid":{"S":"NewestLiveVid"}},{"jobcodeid":{"S":"Very_New_Vid"}},{"jobcodeid":{"S":"Etc_new"}},{"jobcodeid":{"S":"NewLive"}},{"jobcodeid":{"S":"NewLiveVid"}},{"jobcodeid":{"S":"New_Live"}},{"jobcodeid":{"S":"New_Live_Vid"}},{"jobcodeid":{"S":"Newest"}},{"jobcodeid":{"S":"NewestLive"}},{"jobcodeid":{"S":"NewestLiveVid"}},{"jobcodeid":{"S":"Very_New_Vid"}}], obj = {}, new_arr = [];
// in the end the last unique object will be considered
arr.forEach(function(v){
obj[v['jobcodeid']] = v;
});
new_arr = Object.keys(obj).map(function(id) { return obj[id]; });
console.log(JSON.stringify(new_arr));
您应该使用v.jobcodeid.S
作为对象的键。
// exemplary array of objects (id 'NewLive' occurs twice)
var arr=[{"jobcodeid":{"S":"Etc_new"}},{"jobcodeid":{"S":"NewLive"}},{"jobcodeid":{"S":"NewLiveVid"}},{"jobcodeid":{"S":"New_Live"}},{"jobcodeid":{"S":"New_Live_Vid"}},{"jobcodeid":{"S":"Newest"}},{"jobcodeid":{"S":"NewestLive"}},{"jobcodeid":{"S":"NewestLiveVid"}},{"jobcodeid":{"S":"Very_New_Vid"}},{"jobcodeid":{"S":"Etc_new"}},{"jobcodeid":{"S":"NewLive"}},{"jobcodeid":{"S":"NewLiveVid"}},{"jobcodeid":{"S":"New_Live"}},{"jobcodeid":{"S":"New_Live_Vid"}},{"jobcodeid":{"S":"Newest"}},{"jobcodeid":{"S":"NewestLive"}},{"jobcodeid":{"S":"NewestLiveVid"}},{"jobcodeid":{"S":"Very_New_Vid"}}], obj = {}, new_arr = [];
// in the end the last unique object will be considered
arr.forEach(function(v){
obj[v.jobcodeid.S] = v;
});
new_arr = Object.keys(obj).map(function(id) { return obj[id]; });
console.log(JSON.stringify(new_arr));
答案 2 :(得分:1)
发布答案以显示另一种更高效率的方法。
var arr = [
{"jobcodeid":{"S":"Etc_new"}
},
{"jobcodeid":{"S":"NewLive"}
},
{"jobcodeid":{"S":"NewLiveVid"}},
{"jobcodeid":{"S":"New_Live"}},
{"jobcodeid":{"S":"New_Live_Vid"}},
{"jobcodeid":{"S":"Newest"}},
{"jobcodeid":{"S":"NewestLive"}},
{"jobcodeid":{"S":"NewestLiveVid"}},
{"jobcodeid":{"S":"Very_New_Vid"}},
{"jobcodeid":{"S":"Etc_new"}},
{"jobcodeid":{"S":"NewLive"}},
{"jobcodeid":{"S":"NewLiveVid"}},
{"jobcodeid":{"S":"New_Live"}},
{"jobcodeid":{"S":"New_Live_Vid"}},
{"jobcodeid":{"S":"Newest"}},
{"jobcodeid":{"S":"NewestLive"}},
{"jobcodeid":{"S":"NewestLiveVid"}},
{"jobcodeid":{"S":"Very_New_Vid"}}
],
obj = {}, new_arr = [];
// in the end the last unique object will be considered
for (const job of arr) {
if (!obj[job.jobcodeid.S]) {
obj[job.jobcodeid.S] = true;
new_arr.push(job);
}
}
console.log(JSON.stringify(new_arr));
此答案始终运行N次迭代。设置唯一值后在键之间循环时,它最多可以运行2N次迭代。 (从谈论大O /复杂性改为更清晰)
答案 3 :(得分:1)
您需要使用Set
!
const arr = [
{ jobcodeid: { S: "Etc_new" } },
{ jobcodeid: { S: "NewLive" } },
{ jobcodeid: { S: "NewLiveVid" } },
{ jobcodeid: { S: "New_Live" } },
{ jobcodeid: { S: "New_Live_Vid" } },
{ jobcodeid: { S: "Newest" } },
{ jobcodeid: { S: "NewestLive" } },
{ jobcodeid: { S: "NewestLiveVid" } },
{ jobcodeid: { S: "Very_New_Vid" } },
{ jobcodeid: { S: "Etc_new" } },
{ jobcodeid: { S: "NewLive" } },
{ jobcodeid: { S: "NewLiveVid" } },
{ jobcodeid: { S: "New_Live" } },
{ jobcodeid: { S: "New_Live_Vid" } },
{ jobcodeid: { S: "Newest" } },
{ jobcodeid: { S: "NewestLive" } },
{ jobcodeid: { S: "NewestLiveVid" } },
{ jobcodeid: { S: "Very_New_Vid" } }
];
const uniqueItems = [...new Set(arr.map(i => i.jobcodeid.S))]
答案 4 :(得分:0)
也尝试一下。.解决此问题的另一种方法
var arr = [
{"jobcodeid":{"S":"Etc_new"}
},
{"jobcodeid":{"S":"NewLive"}
},
{"jobcodeid":{"S":"NewLiveVid"}},
{"jobcodeid":{"S":"New_Live"}},
{"jobcodeid":{"S":"New_Live_Vid"}},
{"jobcodeid":{"S":"Newest"}},
{"jobcodeid":{"S":"NewestLive"}},
{"jobcodeid":{"S":"NewestLiveVid"}},
{"jobcodeid":{"S":"Very_New_Vid"}},
{"jobcodeid":{"S":"Etc_new"}},
{"jobcodeid":{"S":"NewLive"}},
{"jobcodeid":{"S":"NewLiveVid"}},
{"jobcodeid":{"S":"New_Live"}},
{"jobcodeid":{"S":"New_Live_Vid"}},
{"jobcodeid":{"S":"Newest"}},
{"jobcodeid":{"S":"NewestLive"}},
{"jobcodeid":{"S":"NewestLiveVid"}},
{"jobcodeid":{"S":"Very_New_Vid"}}
],
obj = {}, new_arr = [];
arr.forEach(function(v){
obj[v['id']] = v;
for(var i=0;i< new_arr.length;i++){
if(new_arr[i].jobcodeid.S == v.jobcodeid.S) {
return;
}
}
new_arr.push(v);
});
console.log(new_arr);