我有一个像这样的数组
let arr =
[ { id: 1, name: 'a', age: 10 }
, { id: 2, name: 'a', age: 10 }
, { id: 3, name: 'b', age: 11 }
]
我想删除重复的对象我正在寻找优化解决方案。 解决方案应该是通用的,不应与除“id”属性之外的对象属性名称绑定。 我的意思是它也适用于下面的数组..
[
{id:1, emp_name:'x', sal:33},
{id:2, emp_name:'x', sal:33},
{id:3, emp_name:'z', sal:35}
]
期待
[ { id: 1, name: 'a', age: 10 }
, { id: 3, name: 'b', age: 11 }
]
或
[
{id:1, emp_name:'x', sal:33},
{id:3, emp_name:'z', sal:35}
]
删除数组元素使用
Array.splice()
方法
let arr =
[ { id: 1, name: 'a', age: 10 }
, { id: 2, name: 'a', age: 10 }
, { id: 3, name: 'b', age: 11 }
];
for(let i=arr.length;--i>0;) // need to progress backward
{
if (i > arr.findIndex(e=>e.name===arr[i].name && e.age===arr[i].age))
arr.splice(i,1);
}
console.log(arr)
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
通用解决方案
const
arr1 =
[ { id: 1, name: 'a', age: 10 }
, { id: 2, name: 'a', age: 10 }
, { id: 3, name: 'b', age: 11 }
]
, arr2 =
[ { id:1, emp_name:'x', sal:33 }
, { id:2, emp_name:'x', sal:33 }
, { id:3, emp_name:'z', sal:35 }
];
removeDuplicates(arr1);
console.log('arr1-->', arr1);
removeDuplicates(arr2);
console.log('arr2-->', arr2);
function removeDuplicates(arr)
{
let keys = Object.keys(arr[0]).reduce((kn,k)=>((k==='id')?null:kn.push(k),kn),[]);
// get key names (except 'id')
for(let i=arr.length;--i>0;) // need to progress backward
{
if (i > arr.findIndex(e=>keys.reduce((b,k)=> b && e[k]===arr[i][k] ,true)))
arr.splice(i,1);
}
}
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
我在下面创建了但我正在寻找更优化的..
for(let i=0;i<arr.length;i++)
{
for(let j=i+1;j<arr.length;j++)
{
let o1 = {...arr[i]};
let o2 = {...arr[j]};
delete o1.id ;delete o2.id ;
if(JSON.stringify(o1) === JSON.stringify(o2))
{
arr.splice(i,1);
}
}
}
console.log(JSON.stringify(arr));
我会做这样的事情
const res = arr.reduce(
(acc, x) =>
!acc.has(Object.values(x).slice(1).join(''))
? acc.set(Object.values(x).slice(1).join(''), x)
: acc,
new Map()
)
console.log(Array.from(res.values()))
或者如果你不想制作新的数组、映射等:
for (let i = 0, remove = false; i < arr.length; !remove && i++) {
remove =
arr.findIndex(
(t, ti) =>
ti < i &&
Object.values(arr[i]).every(
(x, j) => j === 0 || x === Object.values(t)[j]
)
) + 1
if (remove) arr.splice(i, 1)
}
您也可以向后循环遍历数组,因此您无需固定索引增量或循环长度。
for (let i = arr.length - 1; i >= 0; i--) {
let duplicateIdx = arr.findIndex(t =>
Object.values(arr[i]).every((x, j) => j === 0 || x === Object.values(t)[j])
)
if (duplicateIdx !== -1 && duplicateIdx < i) arr.splice(i, 1)
}
此外,如果您的 id 属性可能不是第一把钥匙:
for (let i = arr.length - 1; i >= 0; i--) {
let duplicateIdx = arr.findIndex(t =>
Object.keys(arr[i]).every(key => key === 'id' || arr[i][key] === t[key])
)
if (duplicateIdx !== -1 && duplicateIdx < i) arr.splice(i, 1)
}
Set
存储所有已经看到的名称,并使用Array#filter
删除重复项。
let arr = [{id:1,name:'a',age:10},{id:2,name:'a',age:10},{id:3,name:'b',age:11}];
let s = new Set;
let res = arr.filter(x => !s.has(x.name) && s.add(x.name));
console.log(res);