[英]Removing duplicates from array is only returning one object
我正在嘗試從此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。
您的代碼返回單個元素的原因是因為您使用的是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; } }) );
作為記錄,我對公認的解決方案,我的產品以及雅克的答案所帶來的性能改進進行了基准測試
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的解決方案的確速度快一倍,因此,如果您打算過濾大型陣列,或者如果性能是關鍵,則絕對應該選擇它!
首先,您必須使用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));
發布答案以顯示另一種更高效率的方法。
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 /復雜性改為更清楚)
您只需要使用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))]
也可以嘗試此方法..解決此問題的另一種方法
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.