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

时间:2022-09-25 12:37:07

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.

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

8 个解决方案

#1


40  

Use array.prototype.map and array.prototype.some:

使用array.prototype.map和array.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。

#2


24  

ECMA Script 6 Version

ECMA Script 6版本

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

如果您所在的环境支持ECMA Script 6的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 name into the Set and we check if the size before and after adding are the same. This works because Set.size returns 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.

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


ECMA Script 5 Version

ECMA脚本5版

If you don't have Set support, 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.some because it will short-circuit. The moment it gets a truthy value from the function, it will return true immediately, it will not process rest of the elements.

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

#3


2  

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

演示

#4


1  

With Underscore.js A 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 JavaScript By 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 
    });
}

#5


1  

//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);

#6


0  

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

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

var areAnyDuplicates = false;

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

Fiddle

小提琴

#7


0  

To know if simple array has duplicates we can compare first and last indexes 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

#8


0  

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)

#1


40  

Use array.prototype.map and array.prototype.some:

使用array.prototype.map和array.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。

#2


24  

ECMA Script 6 Version

ECMA Script 6版本

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

如果您所在的环境支持ECMA Script 6的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 name into the Set and we check if the size before and after adding are the same. This works because Set.size returns 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.

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


ECMA Script 5 Version

ECMA脚本5版

If you don't have Set support, 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.some because it will short-circuit. The moment it gets a truthy value from the function, it will return true immediately, it will not process rest of the elements.

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

#3


2  

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

演示

#4


1  

With Underscore.js A 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 JavaScript By 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 
    });
}

#5


1  

//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);

#6


0  

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

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

var areAnyDuplicates = false;

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

Fiddle

小提琴

#7


0  

To know if simple array has duplicates we can compare first and last indexes 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

#8


0  

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)