admin管理员组

文章数量:1129706

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.

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.

Share Improve this question edited Jun 9, 2015 at 15:18 thefourtheye 239k53 gold badges464 silver badges500 bronze badges asked Jun 9, 2015 at 14:47 be-codifiedbe-codified 6,11419 gold badges44 silver badges67 bronze badges 1
  • @AmiTavory There's at least one clear difference -- that question looks at an array of primitives (arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];), and this looks at deduping based on the properties of objects. Semantic, perhaps, but the two highest voted answers there don't exactly address this case. /giphy the more you know (I realize that won't do anything) – ruffin Commented Aug 10, 2017 at 20:27
Add a comment  | 

18 Answers 18

Reset to default 146

Use array.prototype.map and 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);

ECMA Script 6 Version

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

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.


ECMA Script 5 Version

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

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.

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.

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')
}

If you need to deal with values, where a property name cannot be guaranteed and your data set is not gigantic, you can use some memory for a pre-filtered array containing the elements you are looking for:

const property = 'name';
const values = [
  { name: 'someName1' },
  { name: 'someName2' },
  { name: 'someName3' },
  { name: 'someName4' },
  { recipe: 'Creamy Mushroom Soup', rating: 4.9 },
  { recipe: 'Butternut Squash Casserole with Leeks', rating: 4.7 }
]

// we are now filtering values we don't want to consider:
const filteredValues = values.filter(v => property in v);
const uniqueValues = new Set(filteredValues.map(v => v[property]));

if (uniqueValues.size < filteredValues.length) {
  console.log('duplicates found')
} else {
  console.log('no duplicates found')
}

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:

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

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

const foundDuplicateName = values.find((nnn, index) =>{
   return values.find((x, ind)=> x.name === nnn.name && index !== ind )
    })
    
    console.log(foundDuplicateName)

Found the first one duplicate name

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

const foundDuplicateName = values.find((nnn, index) =>{
   return values.find((x, ind)=> x.name === nnn.name && index !== ind )
    })

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)

You just need one line of code.

var values = [
        { name: 'someName1' },
        { name: 'someName2' },
        { name: 'someName4' },
        { name: 'someName2' }
     ];
        let hasDuplicates = values.map(v => v.name).length > new Set(values.map(v => v.name)).size ? true : false;

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

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

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.

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

It is quite interesting to work with arrays

You can use new Set() method to find duplicate values!

  • let's assume you have an array of objects like this...

 let myArray = [
            { id: 0, name: "Jhon" },
            { id: 1, name: "sara" },
            { id: 2, name: "pop" },
            { id: 3, name: "sara" }
        ]

const findUnique = new Set(myArray.map(x => {
    return x.name
}))

if(findUnique.size < myArray.length){
    console.log("duplicates found!")
}else{
    console.log("Done!")
}

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

var areAnyDuplicates = false;

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

Fiddle

This code will output an array of objects that have duplicates based on the name property:

const array = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Jane' },
  { id: 3, name: 'John' },
  { id: 4, name: 'Jane' },
  { id: 5, name: 'Adam' }
];

const duplicates = array.reduce((acc, obj, index) => {
  const duplicates = array.filter((item, i) =>
    i !== index && item.name === obj.name
  );

  if (duplicates.length > 0 && !acc.some(dup => dup.name === obj.name)) {
    return acc.concat([obj]);
  }
  return acc;
}, []);

console.log(duplicates);

Adding updated es6 function to check for unique and duplicate values in array. This function is modular and can be reused throughout the code base. Thanks to all the post above.



/* checks for unique keynames in array */
const checkForUnique = (arrToCheck, keyName) => {
    /* make set to remove duplicates and compare to  */
  const uniqueValues = [...new Set(arrToCheck.map(v => v[keyName]))];
  if(arrToCheck.length !== uniqueValues.length){
    console.log('NOT UNIQUE')
    return false
  }
  return true
}


let arr = [{name:'joshua'},{name:'tony'},{name:'joshua'}]

/* call function with arr and key to check for  */
let isUnique = checkForUnique(arr,'name')




checkDuplicate(arr, item) {
   const uniqueValues = new Set(arr.map((v) => v[item]));
   return uniqueValues.size < arr.length;
},

console.log(this.checkDuplicate(this.dutyExemptionBase, 'CI_ExemptionType')); // true || false

No Set, map, or extra variable required. Just use some twice. The first time it finds a duplicate, it returns true. No need to continue looping over the entire array.

const isDuplicate = values.some((e, i) => values.some((f, j) => i === j ? false : e.name === f.name))

Modify the last equality check e.name === f.name to match the property you want to check against.

To find all duplicates in a JavaScript array of objects based on a specific property (in this case, "name"), you can use a combination of reduce() and filter() functions. Here's a way to do it:

var array = [
    {
        "name": "Item A",
        "price": "584.04",
    },
    {
        "name": "Item A",
        "price": "584.04",
    },
    {
        "name": "Item A",
        "price": "584.04",
    },
    {
        "name": "Item B",
        "price": "584.04",
    },
    {
        "name": "Item C",
        "price": "584.04",
    },
    {
        "name": "Item A",
        "price": "584.04",
    },
];

var duplicates = array.reduce(function(acc, current, index, array) {
    if (array.findIndex(item => item.name === current.name) !== index && !acc.find(item => item.name === current.name)) {
        acc.push(current);
    }
    return acc;
}, []);

console.log(duplicates);

const duplicateValues = [{ name: "abc" }, { name: "bcv" }, { name: "abc" }];
const isContainDuplicate = (params) => {
  const removedDuplicate = new Set(params.map((el) => el.name));
  return params.length !== removedDuplicate.size;
};
const isDuplicate = isContainDuplicate(duplicateValues);
console.log("isDuplicate");

本文标签: javascriptHow can I check if the array of objects have duplicate property valuesStack Overflow