如何从具有唯一标识符的 javascript 数组中删除重复项

问题描述 投票:0回答:4

我有一个像这样的数组

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}
    ] 
javascript arrays duplicates
4个回答
1
投票

删除数组元素使用

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;}


0
投票

我在下面创建了但我正在寻找更优化的..

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));

0
投票

我会做这样的事情

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)
}

-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);

© www.soinside.com 2019 - 2024. All rights reserved.