在 JavaScript 中删除对象数组中的重复对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26943242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove duplicate objects in an array of object in JavaScript
提问by Karela Sahiti
Object1 = {connectorIndex: 1, nodeID: 6, Connectors: Object}
Object2 = {connectorIndex: 1, nodeID: 6, Connectors: Object}
Connector: {name: "ALAND", key: "", description: "Departure country (country from which the goods are sent)"}
There are two objects in same array. The connector objects are identical. How do I remove duplicate elements and get the final array with one object?
同一个数组中有两个对象。连接器对象是相同的。如何删除重复元素并使用一个对象获取最终数组?
var array = [object 1, object 2];
object 2
is the duplicate to remove from the array.
object 2
是要从数组中删除的重复项。
回答by Jonathan Crowe
this would do it if you are looking for exact matches:
如果您正在寻找精确匹配,这将做到这一点:
function remove_duplicates(objectsArray) {
var usedObjects = {};
for (var i=objectsArray.length - 1;i>=0;i--) {
var so = JSON.stringify(objectsArray[i]);
if (usedObjects[so]) {
objectsArray.splice(i, 1);
} else {
usedObjects[so] = true;
}
}
return objectsArray;
}
var objectsArray = [{a:'foo',b:'bar'}, {a:'foo',b:'bar'}];
var clean = remove_duplicates(objectsArray);
回答by Bill Ticehurst
The challenge with using JSON.stringify is that if the object might contain a circular reference, then it will throw an exception, e.g.
使用 JSON.stringify 的挑战在于,如果对象可能包含循环引用,那么它将抛出异常,例如
var x1 = {};
x1.a = x1;
JSON.stringify(x1); // <- Uncaught TypeError: Converting circular structure to JSON
As alluded to however, if you are comparing objects and not values, then you can't just do an equality comparison, as this will always be false for different objects (even if they have the same properties with the same values).
然而,正如所提到的,如果您比较的是对象而不是值,那么您不能只进行相等比较,因为对于不同的对象,这总是错误的(即使它们具有相同的属性和相同的值)。
If you were simply comparing values, then something like the below would work
如果您只是简单地比较值,那么类似下面的内容会起作用
var x = [1,2,2,3,4,2,6]; // Source list
var x2 = []; // Will hold the de-duped result
x.forEach(function(elem){if(x2.indexOf(elem) === -1) x2.push(elem);});
x2; // <- [1, 2, 3, 4, 6]
If you want to compare object properties to one level you could write something like the below (there may be an easier way - just whipped this together)
如果您想将对象属性与一个级别进行比较,您可以编写如下所示的内容(可能有更简单的方法 - 只需将其混合在一起)
function sameValues(o1, o2){
for(p in o1){
if(o1[p] !== o2[p]) return false;
}
for(p in o2){
if(o2[p] !== o1[p]) return false;
}
return true;
}
var Object1 = {connectorIndex: 1, nodeID: 6, Connectors: Object};
var Object2 = {connectorIndex: 1, nodeID: 6, Connectors: Object};
var Object3 = {connectorIndex: 1, nodeID: 7, Connectors: Object};
var Object4 = {connectorIndex: 2, nodeID: 7, Connectors: Object};
var Object5 = {connectorIndex: 1, nodeID: 7, Connectors: Object};
var arr = [Object1, Object2, Object3, Object4, Object5];
var result = [];
arr.forEach(function(e1){
if(!result.some(function(e2){return sameValues(e1,e2);})){
// No existing object with same top level values in target array, so add
result.push(e1);
}
});
// result will have the 1st, 3rd, and 4th object only
回答by MAC
This is how I prefer to remove duplicate objects from javascript array-
这就是我更喜欢从 javascript 数组中删除重复对象的方式-
var fieldArray = [{ "name": "tom", "text": "tasty" },{ "name": "ram", "text": "rty" },{ "name": "ram", "text": "rty" },{ "name": "shyam", "text": "tasty" },{"name": "ram", "text": "rty" },{ "name": "tom", "text": "tasty" }];
fieldArray = fieldArray.reduce(function(field, e1){
var matches = field.filter(function(e2){return e1.name== e2.name});
if (matches.length == 0){
field.push(e1);
}return field;
}, []);
alert(JSON.stringify(fieldArray));
This works perfect for me.
这对我来说很完美。
回答by stephen mc
Not sure how performant this is, but I kinda like it for it's succinctness, works for me (its ES6, but Im sure you could figure out the plain ol' ES5):
不确定它的性能如何,但我有点喜欢它的简洁性,对我有用(它的 ES6,但我相信你可以找出简单的 ol' ES5):
let dedupe = (arr, keys) => {
let deduped = [];
arr.forEach(i => {
if (deduped.length === 0) {
deduped.push(i);
} else {
let exists = deduped.find(x => {
return keys.every(key => {
return i[key] === x[key];
});
});
if (!exists) {
deduped.push(i);
}
}
});
return deduped;
};
objArr = dedupe(objArr, ['key', 'test', 'foo']);
回答by darelf
Use an array to hold which items you already have and use filter()
使用数组来保存您已经拥有的项目并使用 filter()
var keys = []
yourArray.filter(function(v) {
if (keys.indexOf(v.whatIAmLookingFor) < 0) {
keys.push(v.whatIAmLookingFor)
return true
}
return false
})
Wrap it in a function and call it a day. Pass in a function for the test, and call it an even better day.
将它包装在一个函数中并称之为一天。为测试传递一个函数,并称它为更好的一天。