提问人:Travis 提问时间:2/8/2010 最后编辑:chickensTravis 更新时间:10/9/2023 访问量:1201371
如何从对象数组中删除所有重复项?
How to remove all duplicates from an array of objects?
问:
我有一个对象,它包含一个对象数组。
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"}
答:
一个原始的方法是:
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]);
}
评论
这是一种通用的执行方法:您传入一个函数,用于测试数组的两个元素是否相等。在本例中,它比较被比较的两个对象的 和 属性的值。name
place
ES5 答案
function removeDuplicates(arr, equals) {
var originalArr = arr.slice(0);
var i, len, val;
arr.length = 0;
for (i = 0, len = originalArr.length; i < len; ++i) {
val = originalArr[i];
if (!arr.some(function(item) { return equals(item, val); })) {
arr.push(val);
}
}
}
function thingsEqual(thing1, thing2) {
return thing1.place === thing2.place
&& thing1.name === thing2.name;
}
var things = [
{place:"here",name:"stuff"},
{place:"there",name:"morestuff"},
{place:"there",name:"morestuff"}
];
removeDuplicates(things, thingsEqual);
console.log(things);
原始 ES3 答案
function arrayContains(arr, val, equals) {
var i = arr.length;
while (i--) {
if ( equals(arr[i], val) ) {
return true;
}
}
return false;
}
function removeDuplicates(arr, equals) {
var originalArr = arr.slice(0);
var i, len, j, val;
arr.length = 0;
for (i = 0, len = originalArr.length; i < len; ++i) {
val = originalArr[i];
if (!arrayContains(arr, val, equals)) {
arr.push(val);
}
}
}
function thingsEqual(thing1, thing2) {
return thing1.place === thing2.place
&& thing1.name === thing2.name;
}
removeDuplicates(things.thing, thingsEqual);
评论
如果可以等到所有添加后才消除重复项,则典型的方法是先对数组进行排序,然后再消除重复项。排序避免了在遍历每个元素时扫描数组中的 N * N 方法。
“消除重复项”功能通常称为 unique 或 uniq。一些现有的实现可能会将这两个步骤结合起来,例如,原型的 uniq
这篇文章几乎没有一些想法可以尝试(还有一些要避免:-))如果您的图书馆还没有!就我个人而言,我认为这是最直接的:
function unique(a){
a.sort();
for(var i = 1; i < a.length; ){
if(a[i-1] == a[i]){
a.splice(i, 1);
} else {
i++;
}
}
return a;
}
// Provide your own comparison
function unique(a, compareFunc){
a.sort( compareFunc );
for(var i = 1; i < a.length; ){
if( compareFunc(a[i-1], a[i]) === 0){
a.splice(i, 1);
} else {
i++;
}
}
return a;
}
评论
function(_a,_b){return _a.a===_b.a && _a.b===_b.b;}
如果你可以使用 Javascript 库,比如 underscore 或 lodash,我建议你看看它们库中的函数。从:_.uniq
lodash
_.uniq(array, [isSorted=false], [callback=_.identity], [thisArg])
基本上,你传入一个数组,这里是一个对象文字,你传入你想在原始数据数组中删除重复项的属性,如下所示:
var data = [{'name': 'Amir', 'surname': 'Rahnama'}, {'name': 'Amir', 'surname': 'Stevens'}];
var non_duplidated_data = _.uniq(data, 'name');
更新:Lodash 现在也推出了一个。.uniqBy
评论
uniqBy
uniq
_.uniqBy(data, 'name')
let data = [{'v': {'t':1, 'name':"foo"}}, {'v': {'t':1, 'name':"bar"}}];
let uniq = _.uniqBy(data, 'v.t');
另一种选择是创建一个自定义 indexOf 函数,该函数比较每个对象所选属性的值,并将其包装在 reduce 函数中。
var uniq = redundant_array.reduce(function(a,b){
function indexOfProperty (a, b){
for (var i=0;i<a.length;i++){
if(a[i].property == b.property){
return i;
}
}
return -1;
}
if (indexOfProperty(a,b) < 0 ) a.push(b);
return a;
},[]);
评论
lodash.isequal
npm 包配对作为轻量级对象比较器以执行独特的数组过滤......例如,不同的对象数组。只是换了进去,而不是看@一个属性if (_.isEqual(a[i], b)) {
如果您只需要按对象的一个字段进行比较,则可以使用数组迭代方法执行此操作的另一种选择:
function uniq(a, param){
return a.filter(function(item, pos, array){
return array.map(function(mapItem){ return mapItem[param]; }).indexOf(item[param]) === pos;
})
}
uniq(things.thing, 'place');
评论
使用一些 ES6 魔法怎么样?
obj.arr = obj.arr.filter((value, index, self) =>
index === self.findIndex((t) => (
t.place === value.place && t.name === value.name
))
)
更通用的解决方案是:
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']);
解释
- 首先了解使用的两种方法:
- 接下来,了解是什么让两个对象相等,并牢记这一点。
- 如果某物满足我们刚才想到的标准,我们可以将其检测为重复项,但它的位置不是具有该标准的对象的第一个实例。
- 因此,我们可以使用上述标准来确定某些内容是否重复。
评论
things.thing = things.thing.filter((thing, index, self) => self.findIndex(t => t.place === thing.place && t.name === thing.name) === index)
const uniqueArray = arrayOfObjects.filter((object,index) => index === arrayOfObjects.findIndex(obj => JSON.stringify(obj) === JSON.stringify(object)));
我有完全相同的要求,根据单个字段上的重复项删除数组中的重复对象。我在这里找到了代码: Javascript:从对象数组中删除重复项
因此,在我的示例中,我将从数组中删除具有重复 licenseNum 字符串值的任何对象。
var arrayWithDuplicates = [
{"type":"LICENSE", "licenseNum": "12345", state:"NV"},
{"type":"LICENSE", "licenseNum": "A7846", state:"CA"},
{"type":"LICENSE", "licenseNum": "12345", state:"OR"},
{"type":"LICENSE", "licenseNum": "10849", state:"CA"},
{"type":"LICENSE", "licenseNum": "B7037", state:"WA"},
{"type":"LICENSE", "licenseNum": "12345", state:"NM"}
];
function removeDuplicates(originalArray, prop) {
var newArray = [];
var lookupObject = {};
for(var i in originalArray) {
lookupObject[originalArray[i][prop]] = originalArray[i];
}
for(i in lookupObject) {
newArray.push(lookupObject[i]);
}
return newArray;
}
var uniqueArray = removeDuplicates(arrayWithDuplicates, "licenseNum");
console.log("uniqueArray is: " + JSON.stringify(uniqueArray));
结果:
uniqueArray 为:
[{"type":"LICENSE","licenseNum":"10849","state":"CA"},
{"type":"LICENSE","licenseNum":"12345","state":"NM"},
{"type":"LICENSE","licenseNum":"A7846","state":"CA"},
{"type":"LICENSE","licenseNum":"B7037","state":"WA"}]
评论
for(var i in array) { if(array[i][prop]){ //valid lookupObject[array[i][prop]] = array[i]; } else { console.log('falsy object'); } }
for (let i in originalArray) { if (lookupObject[originalArray[i]['id']] === undefined) { newArray.push(originalArray[i]); } lookupObject[originalArray[i]['id']] = originalArray[i]; }
您还可以使用:Map
const dedupThings = Array.from(things.thing.reduce((m, t) => m.set(t.place, t), new Map()).values());
完整样本:
const 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"});
const dedupThings = Array.from(things.thing.reduce((m, t) => m.set(t.place, t), new Map()).values());
console.log(JSON.stringify(dedupThings, null, 4));
结果:
[
{
"place": "here",
"name": "stuff"
},
{
"place": "there",
"name": "morestuff"
}
]
评论
一个衬垫使用Set
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"});
// assign things.thing to myData for brevity
var myData = things.thing;
things.thing = Array.from(new Set(myData.map(JSON.stringify))).map(JSON.parse);
console.log(things.thing)
解释:
new Set(myData.map(JSON.stringify))
使用字符串化的 myData 元素创建 Set 对象。- 设置对象将确保每个元素都是唯一的。
- 然后,我使用 Array.from 根据创建的集合的元素创建一个数组。
- 最后,我使用 JSON.parse 将字符串化元素转换回对象。
评论
const distinct = (data, elements = []) => [...new Set(data.map(o => JSON.stringify(o, elements)))].map(o => JSON.parse(o));
distinct
['place', 'name']
['a', 'b']
const objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
评论
向列表中再添加一个。使用 ES6 和 .
在此示例中,基于属性筛选对象。Array.reduce
Array.find
guid
let filtered = array.reduce((accumulator, current) => {
if (! accumulator.find(({guid}) => guid === current.guid)) {
accumulator.push(current);
}
return accumulator;
}, []);
扩展此属性以允许选择属性并将其压缩为一个行:
const uniqify = (array, key) => array.reduce((prev, curr) => prev.find(a => a[key] === curr[key]) ? prev : prev.push(curr) && prev, []);
若要使用它,请将对象数组和要重复数据删除的键的名称作为字符串值传递:
const result = uniqify(myArrayOfObjects, 'guid')
的,孩子们,让我们把这东西压碎,我们为什么不呢?
let uniqIds = {}, source = [{id:'a'},{id:'b'},{id:'c'},{id:'b'},{id:'a'},{id:'d'}];
let filtered = source.filter(obj => !uniqIds[obj.id] && (uniqIds[obj.id] = true));
console.log(filtered);
// EXPECTED: [{id:'a'},{id:'b'},{id:'c'},{id:'d'}];
评论
id
place
name
place
name
ES6 one liner 来了
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}),{})))
评论
:cur
cur.id]:cur
这是 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' }]
评论
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 的值设置为空对象。
接下来,我们过滤对象数组。Filter 创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。
return array.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true));
上面,我们使用 && 的短路功能。如果 && 的左侧计算结果为 true,则返回 && 右侧的值。如果左侧为 false,则返回 &&.
对于每个对象(obj),我们检查uniq中是否有一个名为 obj.id 值的属性(在本例中,在第一次迭代中,它将检查属性“1”。我们想要与它返回的结果相反(无论是 true 还是 false),这就是我们使用 !在。如果 uniq 已经具有 id 属性,则返回 true,其计算结果为 false (!),告诉过滤器函数不要添加该 obj。但是,如果它没有找到 obj.id 属性,则返回 false,然后计算结果为 true (!) 并返回 &&或 (uniq[obj.id] = true) 右侧的所有内容。这是一个真实值,告诉过滤器方法将该 obj 添加到返回的数组中,并且它还将属性 {1: true} 添加到 uniq。这样可以确保不会再次添加具有相同 id 的任何其他 obj 实例。!uniq[obj.id]
要从对象数组中删除所有重复项,最简单的方法是使用:filter
var uniq = {};
var arr = [{"id":"1"},{"id":"1"},{"id":"2"}];
var arrFiltered = arr.filter(obj => !uniq[obj.id] && (uniq[obj.id] = true));
console.log('arrFiltered', arrFiltered);
评论
id
place
name
let myData = [{place:"here",name:"stuff"},
{place:"there",name:"morestuff"},
{place:"there",name:"morestuff"}];
let q = [...new Map(myData.map(obj => [JSON.stringify(obj), obj])).values()];
console.log(q)
使用 ES6 和 .new Map()
// assign things.thing to myData
let myData = things.thing;
[...new Map(myData.map(obj => [JSON.stringify(obj), obj])).values()];
详:-
- 在数据列表上执行操作并将每个单独的对象转换为一对数组(length =2),第一个元素(键)将是对象的版本,第二个元素(值)将是一个本身。
.map()
[key, value]
stringified
object
- 添加上面创建的数组列表会将键作为对象,并且任何相同的键添加都会导致覆盖已经存在的键。
new Map()
stringified
- 使用将为 MapIterator 提供 Map 中的所有值(在我们的例子中)
.values()
obj
- 最后,运算符使用上述步骤中的值给出新的数组。
spread ...
TypeScript 解决方案
这将删除重复的对象并保留对象的类型。
function removeDuplicateObjects(array: any[]) {
return [...new Set(array.map(s => JSON.stringify(s)))]
.map(s => JSON.parse(s));
}
评论
any
一个带过滤器的衬里 ( 保存顺序 )
在数组中查找唯一值。id
arr.filter((v,i,a)=>a.findIndex(v2=>(v2.id===v.id))===i)
如果顺序不重要,地图解决方案会更快:使用地图的解决方案
由多个属性唯一 ( 和place
name
)
arr.filter((v,i,a)=>a.findIndex(v2=>['place','name'].every(k=>v2[k] ===v[k]))===i)
所有属性都是唯一的(对于大型数组,这将很慢)
arr.filter((v,i,a)=>a.findIndex(v2=>(JSON.stringify(v2) === JSON.stringify(v)))===i)
通过将 替换为 来保留上次出现的情况。findIndex
findLastIndex
arr.filter((v,i,a)=>a.findLastIndex(v2=>(v2.place === v.place))===i)
评论
在一行中使用 ES6+,您可以按键获得唯一的对象列表:
const key = 'place';
const unique = [...new Map(arr.map(item => [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 个元素的数组中转换;所选键作为第一个元素,整个初始项作为第二个元素,这称为条目(例如数组条目、映射条目)。这是官方文档,其中包含一个示例,展示了如何在 Map 构造函数中添加数组条目。
放置密钥时的示例:
[["here", {place: "here", name: "x", other: "other stuff1" }], ...]
其次,我们将这个修改后的数组传递给 Map 构造函数,这就是神奇的事情发生。Map 将消除重复的键值,仅保留同一键的最后插入值。注意:地图会保留插入顺序。(检查地图和对象之间的区别)
new Map(上面刚刚映射的条目数组)
第三,我们使用地图值来检索原始项目,但这次没有重复项。
新地图(mappedArr).values()
最后一个是将这些值添加到一个新的数组中,以便它可以看起来像初始结构并返回:
返回 [...new Map(mappedArr).values()]
评论
id
place
name
export const unique = <T extends { [key: string]: unknown }>(arr: T[], key: string): T[] => [ ...new Map(arr.map((item: T) => [item[key], item])).values() ];
这种方式对我来说很有效:
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
}
})
}
这两种方法更简单,更容易理解。
我知道这个问题已经有很多答案了,但请耐心等待......
数组中的某些对象可能具有您不感兴趣的其他属性,或者您只想查找仅考虑属性子集的唯一对象。
考虑下面的数组。假设您想在此数组中查找仅考虑 和 的唯一对象,并忽略可能存在的任何其他属性。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);
评论
array
uniques
propThree
array[0]
someOtherProperty
array[1]
(({ propOne, propTwo }) => ({ propOne, propTwo }))(x)
(x)
propOne
propTwo
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)
通过设置
对象的解决方案 |根据数据类型
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 Object 中的每个值都必须是唯一的,将检查值相等性
设置对象存储唯一值的目的根据数据类型,无论是原始值还是对象 references.it 都有非常有用的四种实例方法 add
、clear
、has
和 delete
。
唯一和数据类型功能:..
Add
方法
默认情况下,它将唯一数据推送到集合中,并保留数据类型。这意味着它可以防止将重复的项目推送到集合中,默认情况下它也会检查数据类型......
has
方法
有时需要检查数据项是否存在于集合中,并且。这是集合的唯一 ID 或项目和数据类型的便捷方法。
Delete
方法
它将通过标识数据类型从集合中删除特定项目。
clear
方法
它将从一个特定变量中删除所有集合项,并设置为空对象
设置
对象还具有迭代方法和更多功能。
最好从这里阅读:Set - JavaScript |MDN网络
简单且高性能的解决方案,具有比现有 70+ 答案更好的运行时间:
const ids = arr.map(({ id }) => id);
const filtered = arr.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(({ id }) => id);
const filtered = arr.filter(({ id }, index) => !ids.includes(id, index + 1));
console.log(filtered);
工作原理:
Array.filter()
通过检查先前映射的 id-array 是否包含当前 id(将对象破坏为仅将其 id 破坏)来删除所有重复的对象。为了只过滤掉实际的重复项,它使用 Array.includes()
的第二个参数,该参数将忽略当前对象和所有以前的对象。{id}
fromIndex
index + 1
由于回调方法的每次迭代只会搜索从当前索引 + 1 开始的数组,这也大大减少了运行时间,因为只有以前未过滤的对象才会被检查。filter
如果您没有像这样的唯一标识符怎么办?id
只需创建一个临时的:
const objToId = ({ name, city, birthyear }) => `${name}-${city}-${birthyear}`;
const ids = arr.map(objToId);
const filtered = arr.filter((item, index) => !ids.includes(objToId(item), index + 1));
评论
{id: 1, name: 'one'}
{namd: 'one', id: 1}
{ id }
id
arr.forEach(object => console.log(object.id))
arr.forEach({id} => console.log(id))
id
arr
我认为最好的方法是使用 reduce 和 Map 对象。这是一条线的解决方案。
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.
*/
评论
这个解决方案最适合我,通过使用 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);
快速(运行时间更短)且类型安全的答案,适用于懒惰的 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
一个带地图的衬里(高性能,不保持顺序)
在数组中查找唯一的 。id
arr
const arrUniq = [...new Map(arr.map(v => [v.id, v])).values()]
如果顺序很重要,请查看带过滤器的解决方案:带过滤器的解决方案
在数组中通过多个属性( 和 ) 唯一place
name
arr
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()
评论
如果数组包含对象,则可以使用它来删除重复项
const persons= [
{ id: 1, name: 'John',phone:'23' },
{ id: 2, name: 'Jane',phone:'23'},
{ id: 1, name: 'Johnny',phone:'56' },
{ id: 4, name: 'Alice',phone:'67' },
];
const unique = [...new Map(persons.map((m) => [m.id, m])).values()];
如果根据手机删除重复项,只需将 m.id 替换为 m.phone
const unique = [...new Map(persons.map((m) => [m.phone, m])).values()];
下一个:按值对对象属性进行排序
评论
arrayWithNoDuplicates = Array.from(new Set(myArray))
Array.from(new Set(myArray.map(e => JSON.stringify(e)))))