Javascript 数组 - 根据另一个 属性 删除重复项
Javascript Array - Remove duplicates based on another property
根据另一个 属性 的值对复杂数组进行重复数据删除的最有效方法是什么?我发现了很多可以对数组或复杂数组进行重复数据删除的示例,但不是这个特定的用例。
我正在尝试查找第 3 列(州)中具有唯一值且第 2 列(许可证)中编号最大的记录
var arrayWithDuplicates = [
["Boat", 1, "NV"],
["Car", 7, "CA"],
["Boat", 3, "NV"],
["Boat", 4, "CA"],
["Car", 5, "OR"],
["Boat", 6, "CA"],
];
期望的结果
var outputArray = [
["Car", 7, "CA"],
["Boat", 3, "NV"],
["Car", 5, "OR"]
];
这可行,但不确定是否适用于大型数据集
var arrayWithDuplicates = [
["Boat", 1, "NV"],
["Car", 7, "CA"],
["Boat", 3, "NV"],
["Boat", 4, "CA"],
["Car", 5, "OR"],
["Boat", 6, "CA"],
];
let arr= arrayWithDuplicates;
let unique = []
for (let i = 0; i < arr.length; i++) {
let found = false;
for (let j = 0; j < unique.length; j++) {
if (arr[i][2] === unique[j][2]) {
found = true;
if (arr[i][1] > unique[j][1]) {
unique[j] = arr[i];
}
break;
}
}
if (!found) {
unique.push(arr[i])
}
}
console.log(unique);
[["Boat", 3, "NV"], ["Boat", 7, "CA"], ["Car", 5, "OR"]]
您可以看到建议解决方案的性能:https://jsbench.me/eskxxcwnhn/1
使用排序和归约
const arrayWithDuplicates = [ ["Boat", 1, "NV"], ["Car", 7, "CA"], ["Boat", 3, "NV"], ["Boat", 4, "CA"], ["Car", 5, "OR"], ["Boat", 6, "CA"], ];
let deduped = [...arrayWithDuplicates]; // take a copy
deduped.sort((a, b) => { // sorts in place
if (a[0] < b[0]) return 1; // sort on names
if (a[0] > b[0]) return -1;
return b[1] - a[1]; // sort on second element
})
// reduce into an object keyed on state
deduped = Object.values( // take only the values from the object
deduped.reduce((acc, cur) => {
const state = cur[2];
if (!acc[state]) acc[state] = cur;
return acc;
},{}))
console.log(deduped)
解决问题的一种方法是使用 Map 实例来保存最相关的值。如果遇到另一个,请更换它。然后,当您完成迭代时,您将获取 Map 实例中存在的值。
const arrayWithDuplicates = [
["Boat", 1, "NV"],
["Car", 7, "CA"],
["Boat", 3, "NV"],
["Boat", 4, "CA"],
["Car", 5, "OR"],
["Boat", 6, "CA"],
];
const lookup = new Map();
for (const record of arrayWithDuplicates) {
const key = record[2];
if (!lookup.has(key)) {
lookup.set(key, record);
continue;
}
const other = lookup.get(key);
if (record[1] > other[1]) {
// Iteration order is based on insertion order. By removing the
// current value first, the new value will be placed at the end.
// If you don't care about the order, deletion can be omitted.
lookup.delete(key);
lookup.set(key, record);
}
}
const result = Array.from(lookup.values());
console.log(result);
请注意,以下代码序列可能是一个相当繁重的操作:
lookup.delete(key);
lookup.set(key, record);
由于它重新排列了地图内容的迭代顺序。这只会按照您要查找的顺序得到结果。如果结果项的顺序无关紧要,则应删除 lookup.delete(key)
调用以提高执行速度。
尽管使用 Map 实例可能会对小型集合产生一些执行开销。当集合变大时,改进的查找速度真正闪耀。
根据另一个 属性 的值对复杂数组进行重复数据删除的最有效方法是什么?我发现了很多可以对数组或复杂数组进行重复数据删除的示例,但不是这个特定的用例。
我正在尝试查找第 3 列(州)中具有唯一值且第 2 列(许可证)中编号最大的记录
var arrayWithDuplicates = [
["Boat", 1, "NV"],
["Car", 7, "CA"],
["Boat", 3, "NV"],
["Boat", 4, "CA"],
["Car", 5, "OR"],
["Boat", 6, "CA"],
];
期望的结果
var outputArray = [
["Car", 7, "CA"],
["Boat", 3, "NV"],
["Car", 5, "OR"]
];
这可行,但不确定是否适用于大型数据集
var arrayWithDuplicates = [
["Boat", 1, "NV"],
["Car", 7, "CA"],
["Boat", 3, "NV"],
["Boat", 4, "CA"],
["Car", 5, "OR"],
["Boat", 6, "CA"],
];
let arr= arrayWithDuplicates;
let unique = []
for (let i = 0; i < arr.length; i++) {
let found = false;
for (let j = 0; j < unique.length; j++) {
if (arr[i][2] === unique[j][2]) {
found = true;
if (arr[i][1] > unique[j][1]) {
unique[j] = arr[i];
}
break;
}
}
if (!found) {
unique.push(arr[i])
}
}
console.log(unique);
[["Boat", 3, "NV"], ["Boat", 7, "CA"], ["Car", 5, "OR"]]
您可以看到建议解决方案的性能:https://jsbench.me/eskxxcwnhn/1
使用排序和归约
const arrayWithDuplicates = [ ["Boat", 1, "NV"], ["Car", 7, "CA"], ["Boat", 3, "NV"], ["Boat", 4, "CA"], ["Car", 5, "OR"], ["Boat", 6, "CA"], ];
let deduped = [...arrayWithDuplicates]; // take a copy
deduped.sort((a, b) => { // sorts in place
if (a[0] < b[0]) return 1; // sort on names
if (a[0] > b[0]) return -1;
return b[1] - a[1]; // sort on second element
})
// reduce into an object keyed on state
deduped = Object.values( // take only the values from the object
deduped.reduce((acc, cur) => {
const state = cur[2];
if (!acc[state]) acc[state] = cur;
return acc;
},{}))
console.log(deduped)
解决问题的一种方法是使用 Map 实例来保存最相关的值。如果遇到另一个,请更换它。然后,当您完成迭代时,您将获取 Map 实例中存在的值。
const arrayWithDuplicates = [
["Boat", 1, "NV"],
["Car", 7, "CA"],
["Boat", 3, "NV"],
["Boat", 4, "CA"],
["Car", 5, "OR"],
["Boat", 6, "CA"],
];
const lookup = new Map();
for (const record of arrayWithDuplicates) {
const key = record[2];
if (!lookup.has(key)) {
lookup.set(key, record);
continue;
}
const other = lookup.get(key);
if (record[1] > other[1]) {
// Iteration order is based on insertion order. By removing the
// current value first, the new value will be placed at the end.
// If you don't care about the order, deletion can be omitted.
lookup.delete(key);
lookup.set(key, record);
}
}
const result = Array.from(lookup.values());
console.log(result);
请注意,以下代码序列可能是一个相当繁重的操作:
lookup.delete(key);
lookup.set(key, record);
由于它重新排列了地图内容的迭代顺序。这只会按照您要查找的顺序得到结果。如果结果项的顺序无关紧要,则应删除 lookup.delete(key)
调用以提高执行速度。
尽管使用 Map 实例可能会对小型集合产生一些执行开销。当集合变大时,改进的查找速度真正闪耀。