英文:
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));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论