如何从对象数组中删除所有重复项?
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
多个属性的唯一性(place
和 name
)
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()
的第二个参数fromIndex
和index + 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 => console.log(object.id))
和 2.arr.forEach(id => console.log(id))
。他们都在做同样的事情:打印arr
中所有对象的id
-key。但是,一种是使用解构,另一种是通过点符号使用更传统的密钥访问。
在这里定义最佳响应。简单干净优雅,像魅力一样工作谢谢!【参考方案6】:
一个带地图的班轮(高性能,不保持秩序)
在数组 arr
中查找唯一的 id
。
const arrUniq = [...new Map(arr.map(v => [v.id, v])).values()]
如果订单很重要,请使用过滤器查看解决方案:Solution with filter
数组arr
中的多个属性(place
和name
)唯一
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) => self.findIndex(t => t.place === thing.place && t.name === thing.name) === index)
@vsync 只需将@BKM 的答案放在一起,一个通用的解决方案是:const uniqueArray = arrayOfObjects.filter((object,index) => index === arrayOfObjects.findIndex(obj => 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
。该问题需要整个对象在所有字段中都是唯一的,例如place
和name
你的 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 你的意思是一个对象的多个重复值? 是的,但更具体地说是具有所有相同值的对象。:cur
在cur.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】:
您可以使用Set
和Filter
方法来完成此操作,
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】:我知道这个问题已经有很多答案了,但请耐心等待......
您的数组中的某些对象可能具有您不感兴趣的其他属性,或者您只是想找到唯一的对象只考虑属性的子集。
考虑下面的数组。假设您想仅考虑 propOne
和 propTwo
来查找此数组中的唯一对象,并忽略可能存在的任何其他属性。
预期结果应仅包括第一个和最后一个对象。代码如下:
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 ) => ( propOne, propTwo ))(x)
?
@knot22 (x)
之前的部分是一个箭头函数,它将参数对象解压缩为属性propOne
和propTwo
。了解对象解构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对象的目的是根据数据类型存储唯一值,无论是原始值还是对象引用。它有四个非常有用的实例方法add
,clear
,has
和delete
。
独特的数据类型功能:..
add
method
默认情况下将唯一数据推送到集合中也保留数据类型。这意味着它可以防止将重复项推送到集合中,默认情况下它会检查数据类型...
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 )
【讨论】:
以上是关于如何从对象数组中删除所有重复项?的主要内容,如果未能解决你的问题,请参考以下文章