如何从对象数组中删除所有重复项?

Posted

技术标签:

【中文标题】如何从对象数组中删除所有重复项?【英文标题】:How to remove all duplicates from an array of objects? 【发布时间】:2011-01-14 05:01:43 【问题描述】:

我有一个包含对象数组的对象。

obj = ;

obj.arr = new Array();

obj.arr.push(place:"here",name:"stuff");
obj.arr.push(place:"there",name:"morestuff");
obj.arr.push(place:"there",name:"morestuff");

我想知道从数组中删除重复对象的最佳方法是什么。例如,obj.arr 将变为...

place:"here",name:"stuff",
place:"there",name:"morestuff"

【问题讨论】:

您的意思是如何停止将所有相同参数添加到数组中的哈希表/对象? Mathew -> 如果首先防止重复对象被添加到数组中更简单,而不是稍后将其过滤掉,是的,那也很好。 Suuuper 的答案很长,但 MDN 的答案可能最短:arrayWithNoDuplicates = Array.from(new Set(myArray)) @tonkatata 这不适用于对象数组。 【参考方案1】:

您可以使用 for 循环和条件使其唯一

const data = [
 id: 1 ,
 id: 2 ,
 id: 3 ,
 id: 4 ,
 id: 5 ,
 id: 6 ,
 id: 6 ,
 id: 6 ,
 id: 7 ,
 id: 8 ,
 id: 8 ,
 id: 8 ,
 id: 8 
];

const filtered= []

for(let i=0; i<data.length; i++ )
    let isHasNotEqual = true
    for(let j=0; j<filtered.length; j++ )
      if (filtered[j].id===data[i].id)
          isHasNotEqual=false
      
    
    if (isHasNotEqual)
        filtered.push(data[i])
    

console.log(filtered);

/*
output
[  id: 1 ,
   id: 2 ,
   id: 3 ,
   id: 4 ,
   id: 5 ,
   id: 6 ,
   id: 7 ,
   id: 8  ]

*/








【讨论】:

【参考方案2】:

我们可以利用Javascript的Set对象和Array的Filter函数: 例如:

// Example Array
const arr = [ id: '1' ,  id: '2' ,  id: '1' ];
// Gather Unique Element Id's based on which you want to filter the elements.
const uniqIds = arr.reduce((ids, el) => ids.add(el.id), new Set());
// Filter out uniq elements.
const uniqElements = arr.filter((el) => uniqIds.delete(el.id));

console.log(uniqElements);

【讨论】:

【参考方案3】:

一个带过滤器的衬垫(保持顺序)

在数组中查找唯一的id

arr.filter((v,i,a)=>a.findIndex(t=>(t.id===v.id))===i)

如果顺序不重要,地图解会更快:Solution with map


多个属性的唯一性(placename

arr.filter((v,i,a)=>a.findIndex(t=>['place','name'].every(k=>t[k] ===v[k]))===i)

所有属性都是唯一的(这对于大型数组来说会很慢)

arr.filter((v,i,a)=>a.findIndex(t=>(JSON.stringify(t) === JSON.stringify(v)))===i)

保留最后一次出现。

arr.filter((v,i,a)=>a.findLastIndex(t=>(t.place === v.place))===i)

【讨论】:

v,i,a == 值、索引、数组 这对于查找我的 vue 模态中的键值对是否有重复非常有用。 +1 arr.filter((v,i,a)=>a.findIndex(t=>(JSON.stringify(t) === JSON.stringify(v)))===i ) 如果键的顺序不同,这将不起作用 t 上的findIndex 代表什么? 简直美丽【参考方案4】:

这是一个带有Set 和一些闭包的单循环方法,以防止在函数声明之外使用声明的变量并获得简短的外观。

const
    array = [ place: "here", name: "stuff", n: 1 ,  place: "there", name: "morestuff", n: 2 ,  place: "there", name: "morestuff", n: 3 ],
    keys = ['place', 'name'],
    unique = array.filter(
        (s => o => (v => !s.has(v) && s.add(v))(keys.map(k => o[k]).join('|')))
        (new Set)
    );

console.log(unique);
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

【参考方案5】:

这是一个运行时间更好的简短 ES6 方法,比已经存在的 70 多个答案:

const ids = array.map(o => o.id)
const filtered = array.filter((id, index) => !ids.includes(id, index + 1))

示例:

const arr = [id: 1, name: 'one', id: 2, name: 'two', id: 1, name: 'one']

const ids = arr.map(o => o.id)
const filtered = arr.filter((id, index) => !ids.includes(id, index + 1))

console.log(filtered)

工作原理:

Array.filter() 通过检查先前映射的 id 数组是否包含当前 id 来删除所有重复的对象(id 将对象分解为仅其 id)。为了只过滤掉实际的重复项,它使用Array.includes() 的第二个参数fromIndexindex + 1,这将忽略当前对象和之前的所有对象。

由于 filter 回调方法的每次迭代都只会搜索从当前索引 + 1 开始的数组,这也大大减少了运行时间,因为只检查以前未过滤的对象。

这显然也适用于任何其他不称为 id 的键,甚至是多个或所有键。

【讨论】:

使用 Set 代替数组有意义吗? @user239558 好问题,但不是真的,它会慢几个数量级,对于具有不同顺序的对象,如 id: 1, name: 'one'namd: 'one', id: 1,它将无法检测到重复项。 你在这里拉的 id 有什么魔力?我正在关注其他所有内容。正要为我自己的目的实现一个 Set 但发现了这个 问得好,@Timotronadon。 id 是destructuring 的对象,只有它的id-key。为了说明这一点,让我们看看这两个循环:1.arr.forEach(object =&gt; console.log(object.id)) 和 2.arr.forEach(id =&gt; console.log(id))。他们都在做同样的事情:打印arr 中所有对象的id-key。但是,一种是使用解构,另一种是通过点符号使用更传统的密钥访问。 在这里定义最佳响应。简单干净优雅,像魅力一样工作谢谢!【参考方案6】:

一个带地图的班轮(高性能,不保持秩序)

在数组 arr 中查找唯一的 id

const arrUniq = [...new Map(arr.map(v => [v.id, v])).values()]

如果订单很重要,请使用过滤器查看解决方案:Solution with filter


数组arr中的多个属性(placename)唯一

const arrUniq = [...new Map(arr.map(v => [JSON.stringify([v.place,v.name]), v])).values()]

数组arr中的所有属性都是唯一的

const arrUniq = [...new Map(arr.map(v => [JSON.stringify(v), v])).values()]

在数组arr中保留第一个匹配项

const arrUniq = [...new Map(arr.slice().reverse().map(v => [v.id, v])).values()].reverse()

【讨论】:

【参考方案7】:

来点es6魔术怎么样?

obj.arr = obj.arr.filter((value, index, self) =>
  index === self.findIndex((t) => (
    t.place === value.place && t.name === value.name
  ))
)

Reference URL

更通用的解决方案是:

const uniqueArray = obj.arr.filter((value, index) => 
  const _value = JSON.stringify(value);
  return index === obj.arr.findIndex(obj => 
    return JSON.stringify(obj) === _value;
  );
);

使用上述属性策略代替JSON.stringify

const isPropValuesEqual = (subject, target, propNames) =>
  propNames.every(propName => subject[propName] === target[propName]);

const getUniqueItemsByProperties = (items, propNames) => 
  items.filter((item, index, array) =>
    index === array.findIndex(foundItem => isPropValuesEqual(foundItem, item, propNames))
  );

如果您希望 propNames 属性为数组或值,则可以添加包装器:

const getUniqueItemsByProperties = (items, propNames) => 
  const propNamesArray = Array.from(propNames);

  return items.filter((item, index, array) =>
    index === array.findIndex(foundItem => isPropValuesEqual(foundItem, item, propNamesArray))
  );
;

同时允许getUniqueItemsByProperties('a')getUniqueItemsByProperties(['a']);

Stackblitz Example

说明

首先了解使用的两种方法: filter, findIndex 接下来考虑是什么让两个对象相等,并牢记这一点。 如果某物满足我们刚刚想到的标准,但它的位置不是符合标准的对象的第一个实例,我们可以将其检测为重复项。 因此,我们可以使用上述标准来确定某些内容是否重复。

【讨论】:

这可以缩短为:things.thing = things.thing.filter((thing, index, self) =&gt; self.findIndex(t =&gt; t.place === thing.place &amp;&amp; t.name === thing.name) === index) @vsync 只需将@BKM 的答案放在一起,一个通用的解决方案是:const uniqueArray = arrayOfObjects.filter((object,index) =&gt; index === arrayOfObjects.findIndex(obj =&gt; JSON.stringify(obj) === JSON.stringify(object)));jsfiddle.net/x9ku0p7L/28 这里的关键是findIndex()方法返回的是first元素的索引,所以如果有第二个元素匹配,就永远找不到添加过滤期间。我盯着它看了一分钟:) 一个问题,这不是 O(n^2) 方法吗?如果我处理 30 条记录,我会进行 900 次迭代,对吗? (最坏的情况,没有重复) 如果您有一个包含 200,000 个条目的数组,那么这将需要 400 亿次迭代。这不应该与大型数组一起使用。始终使用地图。【参考方案8】:

在一行中使用 ES6+,您可以通过键获得唯一的对象列表:

const unique = [...new Map(arr.map((item, key) => [item[key], item])).values()]

可以放入函数中:

function getUniqueListBy(arr, key) 
    return [...new Map(arr.map(item => [item[key], item])).values()]

这是一个工作示例:

const arr = [
    place: "here",  name: "x", other: "other stuff1" ,
    place: "there", name: "x", other: "other stuff2" ,
    place: "here",  name: "y", other: "other stuff4" ,
    place: "here",  name: "z", other: "other stuff5" 
]

function getUniqueListBy(arr, key) 
    return [...new Map(arr.map(item => [item[key], item])).values()]


const arr1 = getUniqueListBy(arr, 'place')

console.log("Unique by place")
console.log(JSON.stringify(arr1))

console.log("\nUnique by name")
const arr2 = getUniqueListBy(arr, 'name')

console.log(JSON.stringify(arr2))

它是如何工作的

首先,数组被重新映射,使其可以用作Map.的输入

arr.map(item => [item[key], item]);

这意味着数组的每一项都将转换为另一个具有 2 个元素的数组; 选定的键作为第一个元素,整个初始项作为第二个元素,这称为条目(例如array entries、map entries)。还有here is the official doc 的示例展示了如何在 Map 构造函数中添加数组条目。

key 为 place 时的示例:

[["here", place: "here",  name: "x", other: "other stuff1" ], ...]

其次,我们将这个修改后的数组传递给 Map 构造函数,这就是神奇的发生。 Map 将消除重复的键值,仅保留同一键的最后插入值。 注意:地图保持插入顺序。 (check difference between Map and object)

new Map(上面刚刚映射的入口数组)

第三次我们使用地图值来检索原始项目,但这次没有重复。

新地图(mappedArr).values()

最后一个是将这些值添加到一个新的数组中,使其看起来像初始结构并返回:

return [...new Map(mappedArr).values()]

【讨论】:

这不回答原始问题,因为这是搜索id。该问题需要整个对象在所有字段中都是唯一的,例如placename 你的 ES6 函数看起来非常简洁实用。你能再解释一下吗?究竟发生了什么?是否删除了第一个或最后一个重复项?或者它是随机的,哪个重复被删除?这会很有帮助,谢谢。 据我所知,创建了一个以属性值为键的 Map。但如何或是否保留数组的顺序并不是 100%。 嗨@DavidSchumann,我会更新答案并解释它是如何工作的。但简而言之,订单被保留,第一个被删除......只要想想它是如何插入到地图中的......它会检查密钥是否已经存在,它将更新它,然后最后一个将保留跨度> null 项或某些项没有调用键的情况下会出错,有什么解决办法吗?【参考方案9】:

ES6 一个班轮来了

let arr = [
  id:1,name:"sravan ganji",
  id:2,name:"pinky",
  id:4,name:"mammu",
  id:3,name:"avy",
  id:3,name:"rashni",
];

console.log(Object.values(arr.reduce((acc,cur)=>Object.assign(acc,[cur.id]:cur),)))

【讨论】:

如果您只想删除具有单个重复值的对象,而不是完全重复的对象,那么干净整洁。 @DavidBarker 你的意思是一个对象的多个重复值? 是的,但更具体地说是具有所有相同值的对象。 :curcur.id]:cur 中的作用是什么?这段代码我看不懂。 使用 lodash( _ ) 我们可以使用 _.uniqBy(arr,'id') 做同样的事情【参考方案10】:

原始方法是:

const obj = ;

for (let i = 0, len = things.thing.length; i < len; i++) 
  obj[things.thing[i]['place']] = things.thing[i];


things.thing = new Array();

 for (const key in obj)  
   things.thing.push(obj[key]);

【讨论】:

你不应该在 for 循环中使用长度,因为它会减慢每次迭代计算它的速度。将其分配给循环外的变量并传递变量而不是 things.thing.length。 @aefxx 这个函数我不是很懂,“地点”相同但名称不同的情况如何处理,是否考虑dup? 虽然这行得通,但它不会处理排序数组,因为从不保证获取键的顺序。所以,你最终再次对其进行排序。现在,假设数组没有排序,但它的顺序很重要,你无法确保顺序保持不变 @DeepakGM 你说得对。答案不会(必然)保留给定的顺序。如果这是一个要求,应该寻找另一种解决方案。 如何修改上述内容以从包含 X 以及重复数据删除的数组中删除对象?【参考方案11】:

为懒惰的 Typescript 开发人员提供快速(更少的运行时间)和类型安全的答案:

export const uniqueBy = <T>( uniqueKey: keyof T, objects: T[]): T[] => 
  const ids = objects.map(object => object[uniqueKey]);
  return objects.filter((object, index) => !ids.includes(object[uniqueKey], index + 1));
 

【讨论】:

uniqueKey 应该是 keyof T 而不是 string 以使其更精确。【参考方案12】:

您可以使用SetFilter 方法来完成此操作,

var arrObj = [
  a: 1,
  b: 2
, 
  a: 1,
  b: 1
, 
  a: 1,
  b: 2
];

var duplicateRemover = new Set();

var distinctArrObj = arrObj.filter((obj) => 
  if (duplicateRemover.has(JSON.stringify(obj))) return false;
  duplicateRemover.add(JSON.stringify(obj));
  return true;
);

console.log(distinctArrObj);

Set 是原始类型的唯一集合,因此不能直接作用于对象,但是JSON.stringify 会将其转换为原始类型,即。 String 这样,我们就可以过滤了。

如果您想仅基于某个特定键删除重复项,例如。 key,你可以用obj.key替换JSON.stringify(obj)

【讨论】:

【参考方案13】:

在这里,我找到了一个使用 reduce 方法从对象数组中删除重复项的简单解决方案。我正在根据对象的位置键过滤元素

const med = [
  name: 'name1', position: 'left',
  name: 'name2', position: 'right',
  name: 'name3', position: 'left',
  name: 'name4', position: 'right',
  name: 'name5', position: 'left',
  name: 'name6', position: 'left1'
]

const arr = [];
med.reduce((acc, curr) => 
  if(acc.indexOf(curr.position) === -1) 
    acc.push(curr.position);
    arr.push(curr);
  
  return acc;
, [])

console.log(arr)

【讨论】:

完美运行。【参考方案14】:

从 React js 中的对象数组中删除重复项(完美运行)

  let optionList = [];
      var dataArr = this.state.itemArray.map(item => 
          return [item.name, item]
      );
  var maparr = new Map(dataArr);

  var results = [...maparr.values()];

  if (results.length > 0) 
       results.map(data => 
       if (data.lead_owner !== null) 
            optionList.push( label: data.name, value: 
            data.name );
       
       return true;
     );
 
 console.log(optionList)

【讨论】:

【参考方案15】:

我知道这个问题已经有很多答案了,但请耐心等待......

您的数组中的某些对象可能具有您不感兴趣的其他属性,或者您只是想找到唯一的对象只考虑属性的子集

考虑下面的数组。假设您想仅考虑 propOnepropTwo 来查找此数组中的唯一对象,并忽略可能存在的任何其他属性。

预期结果应仅包括第一个和最后一个对象。代码如下:

const array = [
    propOne: 'a',
    propTwo: 'b',
    propThree: 'I have no part in this...'
,

    propOne: 'a',
    propTwo: 'b',
    someOtherProperty: 'no one cares about this...'
,

    propOne: 'x',
    propTwo: 'y',
    yetAnotherJunk: 'I am valueless really',
    noOneHasThis: 'I have something no one has'
];

const uniques = [...new Set(
    array.map(x => JSON.stringify(((o) => (
        propOne: o.propOne,
        propTwo: o.propTwo
    ))(x))))
].map(JSON.parse);

console.log(uniques);

【讨论】:

它可以工作但其他属性会被清除,是否可以保留所选对象的其余属性? @ThanwaCh。这是可行的,这实际上是一个偏好问题——只需要确定在重复的情况下应该从哪个对象中获取其余属性。使用我的示例,array 中的第一个和第二个对象成为uniques 中的一个。现在该对象应该包含来自array[0]propThree,还是来自array[1]someOtherProperty,或者两者都包含,还是其他?只要我们确切地知道在这种情况下该怎么做,您所要求的肯定是可行的。 这个解决方案非常适合我编写的用例。你能解释一下这部分是什么/做什么(( propOne, propTwo ) =&gt; ( propOne, propTwo ))(x) @knot22 (x) 之前的部分是一个箭头函数,它将参数对象解压缩为属性propOnepropTwo。了解对象解构here。现在又看了一遍代码,觉得应该写的清楚一点。我已经更新了代码。【参考方案16】:

这个解决方案对我来说效果最好,通过使用 Array.from 方法,而且它更短且可读。

let person = [
name: "john", 
name: "jane", 
name: "imelda", 
name: "john",
name: "jane"
];

const data = Array.from(new Set(person.map(JSON.stringify))).map(JSON.parse);
console.log(data);

【讨论】:

【参考方案17】:
const objectsMap = new Map();
const placesName = [
   place: "here", name: "stuff" ,
   place: "there", name: "morestuff" ,
   place: "there", name: "morestuff" ,
];
placesName.forEach((object) => 
  objectsMap.set(object.place, object);
);
console.log(objectsMap);

【讨论】:

创建对象数组:console.log([...objectsMap.values()]);【参考方案18】:

es6 魔法在一行中...可读!

// returns the union of two arrays where duplicate objects with the same 'prop' are removed
const removeDuplicatesWith = (a, b, prop) => 
  a.filter(x => !b.find(y => x[prop] === y[prop]));
;

【讨论】:

这在两种情况下都不起作用。不仅编辑原始解决方案的两个人通过添加大括号而不是在 a.filter 之前添加 return 语句从根本上改变了它,原始函数无论如何都不起作用,因为它忽略了第二个数组中不在第一个数组中的任何项目.【参考方案19】:

我认为最好的方法是使用reduce 和Map object。 这是单行解决方案。

const data = [
  id: 1, name: 'David',
  id: 2, name: 'Mark',
  id: 2, name: 'Lora',
  id: 4, name: 'Tyler',
  id: 4, name: 'Donald',
  id: 5, name: 'Adrian',
  id: 6, name: 'Michael'
]

const uniqueData = [...data.reduce((map, obj) => map.set(obj.id, obj), new Map()).values()];

console.log(uniqueData)

/*
  in `map.set(obj.id, obj)`
  
  'obj.id' is key. (don't worry. we'll get only values using the .values() method)
  'obj' is whole object.
*/

【讨论】:

任何东西都可以通过删除回车和/或行之间的换行来成为“单行解决方案”:P.【参考方案20】:

如果您使用 Lodash 库,您也可以使用以下函数。它应该删除重复的对象。

var objects = [ 'x': 1, 'y': 2 ,  'x': 2, 'y': 1 ,  'x': 1, 'y': 2 ];
_.uniqWith(objects, _.isEqual);

【讨论】:

【参考方案21】:

 const things = [
  place:"here",name:"stuff",
  place:"there",name:"morestuff",
  place:"there",name:"morestuff"
];
const filteredArr = things.reduce((thing, current) => 
  const x = thing.find(item => item.place === current.place);
  if (!x) 
    return thing.concat([current]);
   else 
    return thing;
  
, []);
console.log(filteredArr)

解决方案通过 Set 对象 |根据数据类型

const seen = new Set();
 const things = [
  place:"here",name:"stuff",
  place:"there",name:"morestuff",
  place:"there",name:"morestuff"
];

const filteredArr = things.filter(el => 
  const duplicate = seen.has(el.place);
  seen.add(el.place);
  return !duplicate;
);
console.log(filteredArr)

Set 对象特征

Set Object 中的每个值都必须是唯一的,将检查值是否相等

Set对象的目的是根据数据类型存储唯一值,无论是原始值还是对象引用。它有四个非常有用的实例方法addclearhasdelete

独特的数据类型功能:..

addmethod

默认情况下将唯一数据推送到集合中也保留数据类型。这意味着它可以防止将重复项推送到集合中,默认情况下它会检查数据类型...

has 方法

有时需要检查数据项是否存在于集合中,并且 .这是收集唯一 ID 或项目和数据类型的便捷方法..

delete 方法

它将通过识别数据类型从集合中删除特定项目..

clear 方法

它将从一个特定变量中删除所有集合项并设置为空对象

Set 对象还具有迭代方法 和更多功能..

从这里更好地阅读: Set - JavaScript | MDN

【讨论】:

【参考方案22】:

问题可以简化为从thing 数组中删除重复项。

您可以实现更快的 O(n) 解决方案(假设本机键查找可以忽略不计),方法是使用一个对象来维护唯一标准作为键并存储关联值。

基本上,这个想法是通过它们的唯一键存储所有对象,以便重复项覆盖它们自己:

const thing = [ place: "here", name:"stuff" ,  place: "there", name:"morestuff" ,  place: "there", name:"morestuff"  ]

const uniques = 
for (const t of thing) 
  const key = t.place + '$' + t.name  // Or whatever string criteria you want, which can be generified as Object.keys(t).join("$")
  uniques[key] = t                    // Last duplicate wins

const uniqueThing = Object.values(uniques)
console.log(uniqueThing)

【讨论】:

【参考方案23】:

这是 ES6 的解决方案,您只想保留最后一项。此解决方案功能强大且符合 Airbnb 风格。

const things = 
  thing: [
     place: 'here', name: 'stuff' ,
     place: 'there', name: 'morestuff1' ,
     place: 'there', name: 'morestuff2' , 
  ],
;

const removeDuplicates = (array, key) => 
  return array.reduce((arr, item) => 
    const removed = arr.filter(i => i[key] !== item[key]);
    return [...removed, item];
  , []);
;

console.log(removeDuplicates(things.thing, 'place'));
// > [ place: 'here', name: 'stuff' ,  place: 'there', name: 'morestuff2' ]

【讨论】:

您可以删除重复项,也可以使用此代码删除所有重复项。不错【参考方案24】:

removeDuplicates() 接受一个对象数组并返回一个没有任何重复对象的新数组(基于 id 属性)。

const allTests = [
  name: 'Test1', id: '1', 
  name: 'Test3', id: '3',
  name: 'Test2', id: '2',
  name: 'Test2', id: '2',
  name: 'Test3', id: '3'
];

function removeDuplicates(array) 
  let uniq = ;
  return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true))


removeDuplicates(allTests);

预期结果:

[
  name: 'Test1', id: '1', 
  name: 'Test3', id: '3',
  name: 'Test2', id: '2'
];

首先,我们将变量 uniq 的值设置为一个空对象。

接下来,我们过滤对象数组。过滤器创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true));

在上面,我们使用了 && 的短路功能。如果 && 左侧的值为真,则返回 && 右侧的值。如果左侧为假,则返回 && 左侧的内容。

对于每个对象(obj),我们检查 uniq 是否有一个名为 obj.id 的属性(在这种情况下,在第一次迭代时,它将检查属性“1”。)我们想要它返回的相反(真或假)这就是我们使用 !在!uniq[obj.id]。如果 uniq 已经有 id 属性,它返回 true ,结果为 false (!) 告诉过滤器函数不要添加那个 obj。但是,如果它没有找到 obj.id 属性,它会返回 false,然后计算结果为 true (!) 并返回 && 右侧的所有内容,或者 (uniq[obj.id] = true)。这是一个真值,告诉 filter 方法将该 obj 添加到返回的数组中,它还将属性 1: true 添加到 uniq。这样可以确保不会再次添加具有相同 id 的任何其他 obj 实例。

【讨论】:

也许解释一下你的代码,以及它是如何回答问题的? 谢谢,mix3d。我添加了说明。 感谢您的解释!这个解决方案对我有用,并且与此处发布的其他几个类似,但我不明白发生了什么:) 谢谢,巧妙的解决方案【参考方案25】:

这种方式对我很有效:

function arrayUnique(arr, uniqueKey) 
  const flagList = new Set()
  return arr.filter(function(item) 
    if (!flagList.has(item[uniqueKey])) 
      flagList.add(item[uniqueKey])
      return true
    
  )

const data = [
  
    name: 'Kyle',
    occupation: 'Fashion Designer'
  ,
  
    name: 'Kyle',
    occupation: 'Fashion Designer'
  ,
  
    name: 'Emily',
    occupation: 'Web Designer'
  ,
  
    name: 'Melissa',
    occupation: 'Fashion Designer'
  ,
  
    name: 'Tom',
    occupation: 'Web Developer'
  ,
  
    name: 'Tom',
    occupation: 'Web Developer'
  
]
console.table(arrayUnique(data, 'name'))// work well

打印输出

┌─────────┬───────────┬────────────────────┐
│ (index) │   name    │     occupation     │
├─────────┼───────────┼────────────────────┤
│    0    │  'Kyle'   │ 'Fashion Designer' │
│    1    │  'Emily'  │   'Web Designer'   │
│    2    │ 'Melissa' │ 'Fashion Designer' │
│    3    │   'Tom'   │  'Web Developer'   │
└─────────┴───────────┴────────────────────┘

ES5:

function arrayUnique(arr, uniqueKey) 
  const flagList = []
  return arr.filter(function(item) 
    if (flagList.indexOf(item[uniqueKey]) === -1) 
      flagList.push(item[uniqueKey])
      return true
    
  )

这两种方式更简单易懂。

【讨论】:

【参考方案26】:
 npm i lodash

 let non_duplicated_data = _.uniqBy(pendingDeposits, v => [v.stellarAccount, v.externalTransactionId].join());

【讨论】:

【参考方案27】:
    function genFilterData(arr, key, key1) 
      let data = [];
      data = [...new Map(arr.map((x) => [x[key] || x[key1], x])).values()];
    
      const makeData = [];
      for (let i = 0; i < data.length; i += 1) 
        makeData.push( [key]: data[i][key], [key1]: data[i][key1] );
      
    
      return makeData;
    
    const arr = [
    make: "here1", makeText:'hj',k:9,l:99,
    make: "here", makeText:'hj',k:9,l:9,
    make: "here", makeText:'hj',k:9,l:9]

      const finalData= genFilterData(data, 'Make', 'MakeText');
    
        console.log(finalData);

【讨论】:

【参考方案28】:
function dupData() 
  var arr = [ comment: ["a", "a", "bbb", "xyz", "bbb"] ];
  let newData = [];
  comment.forEach(function (val, index) 
    if (comment.indexOf(val, index + 1) > -1) 
      if (newData.indexOf(val) === -1)  newData.push(val) 
    
  )

【讨论】:

【参考方案29】:

我的两分钱在这里。如果您知道属性的顺序相同,则可以stringify 元素并从数组中删除重复项并再次解析数组。像这样的:

var things = new Object();

things.thing = new Array();

things.thing.push(place:"here",name:"stuff");
things.thing.push(place:"there",name:"morestuff");
things.thing.push(place:"there",name:"morestuff");
  
let stringified = things.thing.map(i=>JSON.stringify(i));
let unique =  stringified.filter((k, idx)=> stringified.indexOf(k) === idx)
                         .map(j=> JSON.parse(j))
console.log(unique);

【讨论】:

我从来没有想过会这样做。 +1【参考方案30】:

如果您想根据所有参数(而不仅仅是一个参数)对数组进行重复数据删除。您可以使用 lodash 的 uniqBy 函数,该函数可以将函数作为第二个参数。

你将拥有这个单行:

 _.uniqBy(array, e =>  return e.place && e.name )

【讨论】:

以上是关于如何从对象数组中删除所有重复项?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 json 对象键转换为不同的数组来删除重复项

使用 JavaScript 从数组中删除所有重复项 [重复]

从对象数组中的嵌套数组中删除重复项

获取嵌套数组/对象的数组中的所有唯一值(删除重复项)

从 GeoFire 对象数组中删除重复项 [重复]

如何从 javascript 变量中删除对象/数组?