Javascript 如何检查对象数组是否具有重复的属性值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30735465/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:40:51  来源:igfitidea点击:

How can I check if the array of objects have duplicate property values?

javascriptarraysunique

提问by be-codified

I need some help with iterating through array, I keep getting stuck or reinventing the wheel.

我需要一些帮助来迭代数组,我一直被卡住或重新发明轮子。

values = [
    { name: 'someName1' },
    { name: 'someName2' },
    { name: 'someName1' },
    { name: 'someName1' }
]

How could I check if there are two (or more) same name value in array? I do not need a counter, just setting some variable if array values are not unique. Have in mind that array length is dynamic, also array values.

如何检查数组中是否有两个(或更多)相同的名称值?我不需要计数器,如果数组值不唯一,只需设置一些变量。请记住,数组长度是动态的,数组值也是如此。

回答by Amir Popovich

Use array.prototype.mapand array.prototype.some:

使用array.prototype.maparray.prototype.some

var values = [
    { name: 'someName1' },
    { name: 'someName2' },
    { name: 'someName4' },
    { name: 'someName2' }
];

var valueArr = values.map(function(item){ return item.name });
var isDuplicate = valueArr.some(function(item, idx){ 
    return valueArr.indexOf(item) != idx 
});
console.log(isDuplicate);

JSFIDDLE.

JSFIDDLE。

回答by thefourtheye

ECMA Script 6 Version

ECMA 脚本 6 版本

If you are in an environment which supports ECMA Script 6's Set, then you can use Array.prototype.someand a Setobject, like this

如果您处于支持 ECMA Script 6's 的环境中Set,那么您可以使用Array.prototype.some一个Set对象,如下所示

let seen = new Set();
var hasDuplicates = values.some(function(currentObject) {
    return seen.size === seen.add(currentObject.name).size;
});

Here, we insert each and every object's nameinto the Setand we check if the sizebefore and after adding are the same. This works because Set.sizereturns a number based on unique data (set only adds entries if the data is unique). If/when you have duplicate names, the size won't increase (because the data won't be unique) which means that we would have already seen the current name and it will return true.

在这里,我们将每个对象插入name到 中,Set并检查size添加前后是否相同。这是有效的,因为Set.size返回基于唯一数据的数字(如果数据是唯一的,则 set 仅添加条目)。如果/当你有重复的名字时,大小不会增加(因为数据不会是唯一的),这意味着我们已经看到了当前的名字,它会返回 true。



ECMA Script 5 Version

ECMA 脚本 5 版本

If you don't have Setsupport, then you can use a normal JavaScript object itself, like this

如果你没有Set支持,那么你可以使用一个普通的 JavaScript 对象本身,就像这样

var seen = {};
var hasDuplicates = values.some(function(currentObject) {

    if (seen.hasOwnProperty(currentObject.name)) {
        // Current name is already seen
        return true;
    }

    // Current name is being seen for the first time
    return (seen[currentObject.name] = false);
});

The same can be written succinctly, like this

一样可以写得简洁,像这样

var seen = {};
var hasDuplicates = values.some(function (currentObject) {
    return seen.hasOwnProperty(currentObject.name)
        || (seen[currentObject.name] = false);
});


Note:In both the cases, we use Array.prototype.somebecause it will short-circuit. The moment it gets a truthy value from the function, it will return trueimmediately, it will not process rest of the elements.

注意:在这两种情况下,我们都使用Array.prototype.some它,因为它会短路。当它从函数中获得一个真值时,它会true立即返回,它不会处理其余的元素。

回答by TaoPR

With Underscore.jsA few ways with Underscore can be done. Here is one of them. Checking if the array is already unique.

使用 Underscore.js可以使用 Underscore的几种方法。这是其中之一。检查数组是否已经是唯一的。

function isNameUnique(values){
    return _.uniq(values, function(v){ return v.name }).length == values.length
}

With vanilla JavaScriptBy checking if there is no recurring names in the array.

使用 vanilla JavaScript通过检查数组中是否没有重复出现的名称。

function isNameUnique(values){
    var names = values.map(function(v){ return v.name });
    return !names.some(function(v){ 
        return names.filter(function(w){ return w==v }).length>1 
    });
}

回答by Walter Chapilliquen - wZVanG

Try an simple loop:

尝试一个简单的循环:

var repeat = [], tmp, i = 0;

while(i < values.length){
  repeat.indexOf(tmp = values[i++].name) > -1 ? values.pop(i--) : repeat.push(tmp)
}

Demo

演示

回答by Systems Rebooter

To know if simple array has duplicates we can compare firstand lastindexes of the same value:

要知道简单数组是否有重复项,我们可以比较相同值的第一个最后一个索引:

The function:

功能:

var hasDupsSimple = function(array) {

    return array.some(function(value) {                            // .some will break as soon as duplicate found (no need to itterate over all array)
       return array.indexOf(value) !== array.lastIndexOf(value);   // comparing first and last indexes of the same value
    })
}

Tests:

测试:

hasDupsSimple([1,2,3,4,2,7])
// => true

hasDupsSimple([1,2,3,4,8,7])
// => false

hasDupsSimple([1,"hello",3,"bye","hello",7])
// => true

For an array of objects we need to convert the objects values to a simple array first:

对于对象数组,我们需要先将对象值转换为简单数组:

Converting array of objects to the simple array with map:

使用以下命令将对象数组转换为简单数组map

var hasDupsObjects = function(array) {

  return array.map(function(value) {
    return value.suit + value.rank

  }).some(function(value, index, array) { 
       return array.indexOf(value) !== array.lastIndexOf(value);  
     })
}

Tests:

测试:

var cardHand = [
  { "suit":"spades", "rank":"ten" },
  { "suit":"diamonds", "rank":"ace" },
  { "suit":"hearts", "rank":"ten" },
  { "suit":"clubs", "rank":"two" },
  { "suit":"spades", "rank":"three" },
]

hasDupsObjects(cardHand);
// => false


var cardHand2 = [
  { "suit":"spades", "rank":"ten" },
  { "suit":"diamonds", "rank":"ace" },
  { "suit":"hearts", "rank":"ten" },
  { "suit":"clubs", "rank":"two" },
  { "suit":"spades", "rank":"ten" },
]

hasDupsObjects(cardHand2);
// => true

回答by user2167582

if you are looking for a boolean, the quickest way would be

如果您正在寻找布尔值,最快的方法是

var values = [
    { name: 'someName1' },
    { name: 'someName2' },
    { name: 'someName1' },
    { name: 'someName1' }
]

// solution
var hasDuplicate = false;
values.map(v => v.name).sort().sort((a, b) => {
  if (a === b) hasDuplicate = true
})
console.log('hasDuplicate', hasDuplicate)

回答by ravi

//checking duplicate elements in an array
var arr=[1,3,4,6,8,9,1,3,4,7];
var hp=new Map();
console.log(arr.sort());
var freq=0;
for(var i=1;i<arr.length;i++){
// console.log(arr[i-1]+" "+arr[i]);
if(arr[i]==arr[i-1]){
freq++;

}
else{
hp.set(arr[i-1],freq+1);
freq=0;
}
}
console.log(hp);

回答by lukas_o

In TS and ES6 you can create a new Set with the property to be unique and compare it's size to the original array.

在 TS 和 ES6 中,您可以创建一个具有唯一属性的新 Set,并将其大小与原始数组进行比较。

const values = [
  { name: 'someName1' },
  { name: 'someName2' },
  { name: 'someName3' },
  { name: 'someName1' }
]

const uniqueValues = new Set(values.map(v => v.name));

if (uniqueValues.size < values.length) {
  console.log('duplicates found')
}

回答by Omri Aharon

You can use mapto return just the name, and then use this forEachtrick to check if it exists at least twice:

您可以使用map仅返回名称,然后使用此forEach技巧至少检查它是否存在两次:

var areAnyDuplicates = false;

values.map(function(obj) {
    return obj.name;
}).forEach(function (element, index, arr) {
    if (arr.indexOf(element) !== index) {
        areAnyDuplicates = true;
    }
});

Fiddle

小提琴