Ich brauche Hilfe beim Durchlaufen des Arrays, stecke immer wieder fest oder erfinde das Rad neu.
values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
Wie kann ich überprüfen, ob das Array zwei (oder mehr) gleiche Namenswerte enthält? Ich brauche keinen Zähler, sondern setze nur eine Variable, wenn die Array-Werte nicht eindeutig sind. Beachten Sie, dass die Array-Länge dynamisch ist, auch die Array-Werte.
javascript
arrays
unique
kodifiziert werden
quelle
quelle
arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
Diese Frage befasst sich mit einer Reihe von Grundelementen ( ), und dies betrifft die Dedupierung basierend auf den Eigenschaften von Objekten. Vielleicht semantisch, aber die beiden Antworten mit den höchsten Stimmen sprechen diesen Fall nicht genau an./giphy the more you know
(Mir ist klar, dass das nichts bringt)Antworten:
Verwenden Sie array.prototype.map und 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.
quelle
indexOf
wird sehr schlechte Leistung geben, wenn das Array groß ist.ECMA Script 6 Version
Wenn Sie sich in einer Umgebung befinden, die ECMA Script 6 unterstützt
Set
, können SieArray.prototype.some
einSet
Objekt wie dieses verwendenlet seen = new Set(); var hasDuplicates = values.some(function(currentObject) { return seen.size === seen.add(currentObject.name).size; });
Hier fügen wir jedes einzelne Objekt
name
in das einSet
und prüfen, ob diesize
vor und nach dem Hinzufügen gleich sind. Dies funktioniert, weilSet.size
eine Nummer basierend auf eindeutigen Daten zurückgegeben wird (set fügt nur Einträge hinzu, wenn die Daten eindeutig sind). Wenn Sie doppelte Namen haben, wird die Größe nicht erhöht (da die Daten nicht eindeutig sind), was bedeutet, dass wir den aktuellen Namen bereits gesehen haben und er true zurückgibt.ECMA Script 5 Version
Wenn Sie keine
Set
Unterstützung haben, können Sie ein normales JavaScript-Objekt wie dieses verwendenvar 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); });
Das gleiche kann so kurz und bündig geschrieben werden
var seen = {}; var hasDuplicates = values.some(function (currentObject) { return seen.hasOwnProperty(currentObject.name) || (seen[currentObject.name] = false); });
Hinweis: In beiden Fällen verwenden wir,
Array.prototype.some
weil es kurzschließen wird. Sobald die Funktion einen wahrheitsgemäßen Wert erhält, kehrt sietrue
sofort zurück und verarbeitet die restlichen Elemente nicht.quelle
hasOwnProperty
. Ich habe in einigen anderen Antworten gesehen, die Sie kommentiertindexOf
haben und die in großen Arrays eine schlechte Leistung haben werden. Ist die oben beschriebene ES5-Methode, die Sie vorgeschlagen haben, für größere Objekte im Allgemeinen leistungsfreundlicher?indexOf
muss das Array iterieren, um herauszufinden, ob das Element vorhanden ist oder nicht, aber alles, was Hashing verwendet, ist viel schneller. Wenn das Array ziemlich groß ist, sind sowohl die ES5- als auch die ES6-Methode viel schneller.forEach
und schreiben Sie die Logik selbst.In TS und ES6 können Sie ein neues Set mit der Eigenschaft erstellen, dass es eindeutig ist, und seine Größe mit dem ursprünglichen Array vergleichen.
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') }
quelle
Die Funktion:
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
Konvertieren eines Array von Objekten in ein einfaches Array mit
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
quelle
Wenn Sie nach einem Booleschen Wert suchen, ist der schnellste Weg
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)
quelle
Mit Underscore.js Mit Underscore gibt es einige Möglichkeiten. Hier ist einer von ihnen. Überprüfen, ob das Array bereits eindeutig ist.
function isNameUnique(values){ return _.uniq(values, function(v){ return v.name }).length == values.length }
Mit Vanille-JavaScript Überprüfen Sie, ob das Array keine wiederkehrenden Namen enthält.
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 }); }
quelle
Versuchen Sie eine einfache Schleife:
var repeat = [], tmp, i = 0; while(i < values.length){ repeat.indexOf(tmp = values[i++].name) > -1 ? values.pop(i--) : repeat.push(tmp) }
Demo
quelle
Mit können Sie
map
nur den Namen zurückgeben und dann mit diesemforEach
Trick überprüfen, ob er mindestens zweimal vorhanden ist:var areAnyDuplicates = false; values.map(function(obj) { return obj.name; }).forEach(function (element, index, arr) { if (arr.indexOf(element) !== index) { areAnyDuplicates = true; } });
Geige
quelle
indexOf
wird sehr schlechte Leistung geben, wenn das Array groß ist.//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);
quelle