英文:
How to Remove duplicates from javascript array having one unique identifier
问题
我有一个数组如下:
```lang-js
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}
]
英文:
I have an array like
let arr =
[ { id: 1, name: 'a', age: 10 }
, { id: 2, name: 'a', age: 10 }
, { id: 3, name: 'b', age: 11 }
]
I want to remove duplicate objects I am looking for an optimize solution.
solution should be generic and should not be bound with object properties name except "id" property.
I mean it should work for below array also ..
[
{id:1, emp_name:'x', sal:33},
{id:2, emp_name:'x', sal:33},
{id:3, emp_name:'z', sal:35}
]
I am expecting
[ { id: 1, name: 'a', age: 10 }
, { id: 3, name: 'b', age: 11 }
]
or
[
{id:1, emp_name:'x', sal:33},
{id:3, emp_name:'z', sal:35}
]
答案1
得分: 1
使用`Array.splice()`方法来删除数组元素
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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;) // 需要从后往前处理
{
if (i > arr.findIndex(e=>e.name===arr[i].name && e.age===arr[i].age))
arr.splice(i,1);
}
console.log(arr)
<!-- language: lang-css -->
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
<!-- end snippet -->
**通用解决方案**
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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),[]);
// 获取键名(除'id'外的)
for(let i=arr.length;--i>0;) // 需要从后往前处理
{
if (i > arr.findIndex(e=>keys.reduce((b,k)=> b && e[k]===arr[i][k] ,true)))
arr.splice(i,1);
}
}
<!-- language: lang-css -->
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
<!-- end snippet -->
英文:
to REMOVE an array element use Array.splice()
method
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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)
<!-- language: lang-css -->
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
<!-- end snippet -->
Generic solution
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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);
}
}
<!-- language: lang-css -->
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}
<!-- end snippet -->
答案2
得分: 0
我会做这样的事情
```javascript
或者如果你不想创建新的数组、映射等等:
```javascript
你也可以反向循环数组,这样就不需要修复索引递增或循环的长度。
```javascript
此外,如果你的id属性可能不是第一个键:
```javascript
英文:
I would do something like this
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()))
Or if you don't want to make new arrays, maps and so on:
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)
}
You can loop through array backwards as well so you don't need to fix the index increment or the length of loop.
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)
}
Also if your id property may not be the 1st key:
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)
}
答案3
得分: 0
我已经创建了下面的代码,但我正在寻找一个更优化的版本。。
英文:
I have created below but I am looking for more optimized one ..
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));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论