Come posso verificare se la matrice di oggetti ha valori di proprietà duplicati?

Ho bisogno di aiuto con l’iterazione attraverso l’array, continuo a rimanere bloccato o a reinventare la ruota.

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

Come potrei verificare se ci sono due (o più) valori di nome nello stesso array? Non ho bisogno di un contatore, semplicemente impostando alcune variabili se i valori dell’array non sono univoci. Tieni presente che la lunghezza dell’array è dynamic, anche i valori dell’array.

Usa array.prototype.map e 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.

ECMA Script 6 Version

Se ci si trova in un ambiente che supporta il Set di ECMA Script 6, è ansible utilizzare Array.prototype.some e un object Set , come questo

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

Qui, inseriamo il name ogni object nel Set e controlliamo se le size prima e dopo l’aggiunta sono le stesse. Funziona perché Set.size restituisce un numero basato su dati univoci (imposta solo aggiunge voci se i dati sono univoci). Se / quando hai nomi duplicati, le dimensioni non aumenteranno (perché i dati non saranno univoci), il che significa che avremmo già visto il nome corrente e restituirà true.


ECMA Script 5 Version

Se non hai Set supporto, puoi utilizzare un normale object JavaScript, come questo

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

Lo stesso può essere scritto succintamente, come questo

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

Nota: in entrambi i casi, usiamo Array.prototype.some perché andrà in corto circuito. Nel momento in cui ottiene un valore di verità dalla funzione, restituirà true immediatamente, non elaborerà il resto degli elementi.

Prova un ciclo semplice:

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

dimostrazione

Con Underscore.js Si possono fare alcuni modi con Underscore. Ecco uno di loro. Verifica se l’array è già univoco.

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

Con vaniglia JavaScript Controllando se non ci sono nomi ricorrenti nella matrice.

 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 

Puoi utilizzare la map per restituire solo il nome, quindi utilizzare questo trucco forEach per verificare se esiste almeno due volte:

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

Violino

Per sapere se la matrice semplice ha duplicati, possiamo confrontare il primo e l’ ultimo indice dello stesso valore:

La funzione:

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

test:

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

Per una serie di oggetti, dobbiamo prima convertire i valori degli oggetti in un array semplice:

Convertire la matrice di oggetti nella matrice semplice con la 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); }) } 

test:

 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 

se stai cercando un booleano, il modo più veloce sarebbe

 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)