wake-up-neo.com

Alle eindeutigen Werte in einem JavaScript-Array abrufen (Duplikate entfernen)

Ich habe eine Reihe von Zahlen, die ich sicherstellen muss, um eindeutig zu sein. Ich habe das Code-Snippet unten im Internet gefunden und es funktioniert gut, bis das Array eine Null enthält. Ich habe dieses andere Skript hier auf SO gefunden, das fast genau so aussieht, aber es scheitert nicht.

Kann mir jemand helfen zu lernen, wo das Prototyp-Skript schief geht?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.Push (e)};
 return a;
}

Weitere Antworten aus doppelter Frage:

Ähnliche Frage:

987
Mottie

Mit JavaScript 1.6/ECMAScript 5 können Sie die native filter -Methode eines Arrays folgendermaßen verwenden, um ein Array mit eindeutigen Werten zu erhalten:

function onlyUnique(value, index, self) { 
    return self.indexOf(value) === index;
}

// usage example:
var a = ['a', 1, 'a', 2, '1'];
var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

Die native Methode filter durchläuft das Array und hinterlässt nur die Einträge, die die angegebene Callback-Funktion onlyUnique übergeben.

onlyUnique prüft, ob der angegebene Wert der erste ist. Wenn nicht, muss es ein Duplikat sein und wird nicht kopiert.

Diese Lösung funktioniert ohne zusätzliche Bibliothek wie jQuery oder prototype.js.

Es funktioniert auch für Arrays mit gemischten Werttypen.

Für alte Browser (<ie9), die die systemeigenen Methoden filter und indexOf nicht unterstützen, finden Sie in der MDN-Dokumentation Umgehungen für filter und indexOf .

Wenn Sie das letzte Vorkommen eines Werts beibehalten möchten, ersetzen Sie einfach indexOf durch lastIndexOf

Mit ES6 könnte man es abkürzen:

// usage example:
var myArray = ['a', 1, 'a', 2, '1'];
var unique = myArray.filter((v, i, a) => a.indexOf(v) === i); 

// unique is ['a', 1, 2, '1']

Danke an Camilo Martin für den Hinweis im Kommentar. 

ES6 verfügt über ein natives Objekt Set , um eindeutige Werte zu speichern. Um ein Array mit eindeutigen Werten zu erhalten, können Sie jetzt Folgendes tun:

var myArray = ['a', 1, 'a', 2, '1'];

let unique = [...new Set(myArray)]; 

// unique is ['a', 1, 2, '1']

Der Konstruktor von Set nimmt ein iterierbares Objekt wie Array und der Spread-Operator ... wandelt den Satz zurück in ein Array. Danke an Lukas Liese für den Hinweis im Kommentar.

1876
TLindig

Aktualisierte Antwort für ES6/ES2015: Bei Verwendung von Set lautet die einzeilige Lösung:

var items = [4,5,4,6,3,4,5,2,23,1,4,4,4]
var uniqueItems = Array.from(new Set(items))

Welche zurückkehrt 

[4, 5, 6, 3, 2, 23, 1]

Wie le_m vorgeschlagen, kann dies auch mit spread Operator gekürzt werden

var uniqueItems = [...new Set(items)]
642
A.T.

Sie können auch nderscore.js verwenden.

console.log(_.uniq([1, 2, 1, 3, 1, 4]));
<script src="http://underscorejs.org/underscore-min.js"></script>

was zurückkommt:

[1, 2, 3, 4]
130
kornfridge

Ich weiß, dass diese Frage bereits mehr als 30 Antworten hat. Ich habe aber zuerst alle vorhandenen Antworten durchgelesen und meine eigenen Nachforschungen angestellt.

Ich teile alle Antworten in 4 mögliche Lösungen auf:

  1. Verwenden Sie die neue ES6-Funktion: [...new Set( [1, 1, 2] )];
  2. Verwenden Sie das Objekt { }, um Duplikate zu verhindern
  3. Helper-Array verwenden [ ]
  4. Verwenden Sie filter + indexOf

Hier finden Sie Beispielcodes, die in Antworten gefunden wurden:

Verwenden Sie die neue ES6-Funktion: [...new Set( [1, 1, 2] )];

function uniqueArray0(array) {
  var result = Array.from(new Set(array));
  return result    
}

Verwenden Sie das Objekt { }, um Duplikate zu verhindern

function uniqueArray1( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });

  return Object.keys(j).map(function(v){
    return j[v];
  });
} 

Helper-Array verwenden [ ]

function uniqueArray2(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.Push(arr[i]);
    return a;
}

Verwenden Sie filter + indexOf

function uniqueArray3(a) {
  function onlyUnique(value, index, self) { 
      return self.indexOf(value) === index;
  }

  // usage
  var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

  return unique;
}

Und ich habe mich gefragt, welche schneller ist. Ich habe sample Google Sheet gemacht, um Funktionen zu testen. Hinweis: ECMA 6 ist in Google Sheets nicht verfügbar. Daher kann ich es nicht testen.

Hier ist das Ergebnis der Tests:  enter image description here

Ich habe erwartet, dass der Code mit dem Objekt { } gewonnen wird, da er Hash verwendet. Daher bin ich froh, dass Tests in Chrome und IE die besten Ergebnisse für diesen Algorithmus ergeben haben. Danke an @rab für den Code .

117
Max Makhrov

Ein Liner, reines JavaScript

Mit ES6-Syntax

list = list.filter((x, i, a) => a.indexOf(x) == i)

x --> item in array
i --> index of item
a --> array reference, (in this case "list")

enter image description here

Mit ES5-Syntax

list = list.filter(function (x, i, a) { 
    return a.indexOf(x) == i; 
});

Browserkompatibilität : IE9 +

58
Vamsi

Ich habe eine Nice-Methode gefunden, die jQuery verwendet

arr = $.grep(arr, function(v, k){
    return $.inArray(v ,arr) === k;
});

Hinweis: Dieser Code wurde aus Paul Irishs Entenstichposten - Ich habe vergessen, die Anerkennung zu vergeben: P

50
Mottie

Kürzeste Lösung mit ES6: [...new Set( [1, 1, 2] )];

Oder wenn Sie den Array-Prototyp ändern möchten (wie in der ursprünglichen Frage):

Array.prototype.getUnique = function() {
    return [...new Set( [this] )];
};

EcmaScript 6 ist derzeit nur in einigen Browsern (August 2015) teilweise implementiert , aber Babel ist sehr beliebt geworden, um ES6 (und sogar ES7) wieder auf ES5 umzuwandeln. Auf diese Weise können Sie heute noch ES6-Code schreiben!

Wenn Sie sich fragen, was der ... bedeutet, wird er als spread-Operator bezeichnet. Aus MDN : «Mit dem Spread-Operator kann ein Ausdruck an Stellen erweitert werden, an denen mehrere Argumente (für Funktionsaufrufe) oder mehrere Elemente (für Array-Literale) erwartet werden». Da ein Set ein Iterer ist (und nur eindeutige Werte haben kann), erweitert der Spread-Operator den Satz, um das Array zu füllen.

Ressourcen zum Lernen von ES6:

45
Torsten Becker

Einfachste Lösung:

var arr = [1, 3, 4, 1, 2, 1, 3, 3, 4, 1];
console.log([...new Set(arr)]);

Oder:

var arr = [1, 3, 4, 1, 2, 1, 3, 3, 4, 1];
console.log(Array.from(new Set(arr)));

32
Pedro L.

Der einfachste und schnellste (in Chrome) Weg, dies zu tun:

Array.prototype.unique = function() {
    var a = [];
    for (var i=0, l=this.length; i<l; i++)
        if (a.indexOf(this[i]) === -1)
            a.Push(this[i]);
    return a;
}

Führt einfach jedes Element im Array durch, prüft, ob das Element bereits in der Liste enthalten ist, und wenn nicht, drücken Sie auf das Array, das zurückgegeben wird.

Laut jsPerf ist diese Funktion die schnellste von denen, die ich überall finden könnte - Sie können jedoch gerne Ihre eigene hinzufügen.

Die Nicht-Prototyp-Version:

function uniques(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.Push(arr[i]);
    return a;
}

Sortierung

Wenn auch das Array sortiert werden muss, ist das Folgende am schnellsten:

Array.prototype.sortUnique = function() {
    this.sort();
    var last_i;
    for (var i=0;i<this.length;i++)
        if ((last_i = this.lastIndexOf(this[i])) !== i)
            this.splice(i+1, last_i-i);
    return this;
}

oder Nicht-Prototyp:

function sortUnique(arr) {
    arr.sort();
    var last_i;
    for (var i=0;i<arr.length;i++)
        if ((last_i = arr.lastIndexOf(arr[i])) !== i)
            arr.splice(i+1, last_i-i);
    return arr;
}

Dies ist auch schneller als die obige Methode in den meisten Nicht-Chrome-Browsern.

30
Joeytje50

NUR LEISTUNG! Dieser Code ist wahrscheinlich 10x schneller als alle Codes hier * funktioniert in allen Browsern und hat auch die geringste Auswirkung auf den Speicher .... und mehr

wenn Sie das alte Array nicht wiederverwenden müssen, ist es wahrscheinlich der schnellste Weg, dies zu tun, auch sehr kurz.

var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];

dann kannst du das probieren

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1];

function toUnique(a, b, c) { //array,placeholder,placeholder
  b = a.length;
  while (c = --b)
    while (c--) a[b] !== a[c] || a.splice(c, 1);
  return a // not needed ;)
}
console.log(toUnique(array));
//[3, 4, 5, 6, 7, 8, 9, 0, 2, 1]

Ich habe mir diese Funktion ausgedacht, als ich diesen Artikel gelesen habe ...

http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/

Ich mag die for-Schleife nicht. es hat zu viele parameter. ich mag die while-- schleife. while ist die schnellste Schleife in allen Browsern, außer der, die wir alle so sehr mögen ... chrome.

trotzdem habe ich die erste Funktion geschrieben, die while verwendet. Und yep, es ist ein bisschen schneller als die im Artikel gefundene Funktion. Aber nicht genug .unique2()

im nächsten Schritt verwende moderne js. Object.keys Ich habe die andere for-Schleife durch die Object.keys von js1.7 ersetzt ... etwas schneller und kürzer (in chrome 2x schneller);) . Nicht genug! .unique3().

zu diesem Zeitpunkt dachte ich darüber nach, was ich in MEINER einzigartigen Funktion wirklich brauche. Ich brauche das alte Array nicht, ich möchte eine schnelle Funktion. Also habe ich 2 while-Schleifen + Spleiß verwendet .unique4()

Unnötig zu sagen, dass ich beeindruckt war.

chrome: Die üblichen 150.000 Operationen pro Sekunde stiegen auf 1.800.000 Operationen pro Sekunde.

ie: 80.000 op/s gegenüber 3.500.000 op/s

ios: 18.000 Operationen gegenüber 170.000 Operationen

safari: 80.000 op/s gegen 6.000.000 op/s

Beweis http://jsperf.com/wg oder besser console.time ... microtime ... was auch immer

unique5() soll Ihnen nur zeigen, was passiert, wenn Sie das alte Array behalten möchten.

Verwenden Sie nicht Array.prototype, Wenn Sie nicht wissen, was Sie tun. Ich habe gerade viel kopiert und vergangen. Verwenden Sie Object.defineProperty(Array.prototype,...,writable:false,enumerable:false}), wenn Sie einen nativen Prototyp erstellen möchten. Beispiel: https://stackoverflow.com/a/20463021/24507

Demo http://jsfiddle.net/46S7g/

ANMERKUNG: Ihr altes Array wird nach dieser Operation zerstört/zu einem Unikat.

wenn Sie den obigen Code nicht lesen können, lesen Sie ein Javascript-Buch oder hier einige Erklärungen zu kürzerem Code. https://stackoverflow.com/a/21353032/24507

einige verwenden indexOf ... nicht ... http://jsperf.com/dgfgghfghfghghgfhgfhfghfhgfh

für leere Arrays

!array.length||toUnique(array); 
29
cocco

Viele der Antworten sind für Anfänger möglicherweise nicht hilfreich. Wenn das De-Dupen eines Arrays schwierig ist, wissen sie dann wirklich etwas über die Prototypkette oder sogar über jQuery?

In modernen Browsern ist es eine saubere und einfache Lösung, Daten in einem Set zu speichern, das als Liste eindeutiger Werte konzipiert ist.

const cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
const uniqueCars = Array.from(new Set(cars));

Der Array.from ist nützlich, um das Set zurück in ein Array zu konvertieren, sodass Sie auf alle fantastischen Methoden (Features) von Arrays zugreifen können. Es gibt auch andere Wege das Gleiche zu tun. Möglicherweise benötigen Sie Array.from jedoch nicht, da Sets viele nützliche Funktionen wie forEach enthalten.

Wenn Sie den alten Internet Explorer unterstützen müssen und daher Set nicht verwenden können, kopieren Sie Elemente in ein neues Array, und überprüfen Sie vorher, ob sie bereits im neuen Array enthalten sind.

// Create a list of cars, with duplicates.
var cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
// Create a list of unique cars, to put a car in if we haven't already.
var uniqueCars = [];

// Go through each car, one at a time.
cars.forEach(function (car) {
    // The code within the following block runs only if the
    // current car does NOT exist in the uniqueCars list
    // - a.k.a. prevent duplicates
    if (uniqueCars.indexOf(car) === -1) {
        // Since we now know we haven't seen this car before,
        // copy it to the end of the uniqueCars list.
        uniqueCars.Push(car);
    }
});

Um dies sofort wiederverwendbar zu machen, setzen wir es in eine Funktion.

function deduplicate(data) {
    if (data.length > 0) {
        var result = [];

        data.forEach(function (elem) {
            if (result.indexOf(elem) === -1) {
                result.Push(elem);
            }
        });

        return result;
    }
}

Um die Duplikate loszuwerden, würden wir das jetzt tun.

var uniqueCars = deduplicate(cars);

Der deduplicate(cars)-Teil wird zu der Sache, die wir Ergebnis genannt haben, wenn die Funktion abgeschlossen ist.

Geben Sie einfach den Namen eines beliebigen Arrays an.

24
Seth Holladay
["Defects", "Total", "Days", "City", "Defects"].reduce(function(prev, cur) {
  return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
 }, []);

[0,1,2,0,3,2,1,5].reduce(function(prev, cur) {
  return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
 }, []);
19
sergeyz

Dieser Prototyp getUnique ist nicht völlig korrekt, denn wenn ich ein Array wie: ["1",1,2,3,4,1,"foo"] habe, wird ["1","2","3","4"] zurückgegeben und "1" ist string und 1 ist eine ganze Zahl. Sie sind anders.

Hier ist eine richtige Lösung:

Array.prototype.unique = function(a){
    return function(){ return this.filter(a) }
}(function(a,b,c){ return c.indexOf(a,b+1) < 0 });

mit:

var foo;
foo = ["1",1,2,3,4,1,"foo"];
foo.unique();

Das obige wird ["1",2,3,4,1,"foo"] erzeugen.

17

Wir können dies mit ES6-Sets tun:

var duplicatedArray = [1,2,3,4,5,1,1,1,2,3,4];
var uniqueArray = Array.from(new Set(duplicatedArray));

// Die Ausgabe wird sein 

uniqueArray = [1,2,3,4,5];
12
chinmayan

Ohne die Erweiterung von Array.prototype (dies soll eine schlechte Praxis sein) oder die Verwendung von Jquery/Unterstrich, können Sie das Array einfach filter verwenden.

Beim letzten Auftreten halten:

    function arrayLastUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps last occurrence
            return c.indexOf(a, b + 1) < 0;
        });
    },

oder erstes Auftreten:

    function arrayFirstUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps first occurrence
            return c.indexOf(a) === b;
        });
    },

Nun, es ist nur Javascript ECMAScript 5+, was nur IE9 + bedeutet, aber es ist Nizza für eine Entwicklung in nativem HTML/JS (Windows Store App, Firefox OS, Sencha, Phonegap, Titanium, ...).

12
Cœur

Das liegt daran, dass 0 in JavaScript ein falscher Wert ist.

this[i] ist falsch, wenn der Wert des Arrays 0 oder ein anderer falscher Wert ist.

10
Luca Matteis

Wenn Sie das Prototype-Framework verwenden, müssen Sie keine for-Schleifen ausführen. Sie können http://www.prototypejs.org/api/array/uniq wie folgt verwenden:

var a = Array.uniq();  

Dadurch wird ein doppeltes Array ohne Duplikate erzeugt. Ich bin auf Ihre Frage gestoßen, als ich nach einer Methode suchte, um verschiedene Array-Datensätze zu zählen 

uniq ()

Ich benutzte 

größe()

und es war mein einfaches Ergebnis. p. Entschuldigung, wenn ich etwas falsch geschrieben habe

bearbeiten: Wenn Sie undefinierte Datensätze mit einem Escape-Befehl versehen möchten, können Sie sie hinzufügen 

kompakt() 

vorher wie folgt:

var a = Array.compact().uniq();  
10
Decebal
Array.prototype.getUnique = function() {
    var o = {}, a = []
    for (var i = 0; i < this.length; i++) o[this[i]] = 1
    for (var e in o) a.Push(e)
    return a
}
9
ephemient

seltsam, dies wurde zuvor nicht vorgeschlagen. Um Duplikate mit dem Objektschlüssel (id unten) in einem Array zu entfernen, können Sie Folgendes tun:

const uniqArray = array.filter((obj, idx, arr) => (
  arr.findIndex((o) => o.id === obj.id) === idx
)) 
6
daviestar

Ich bin nicht sicher, warum Gabriel Silveira die Funktion so geschrieben hat, aber eine einfachere Form, die für mich genauso gut und ohne die Minifikation funktioniert, ist:

Array.prototype.unique = function() {
  return this.filter(function(value, index, array) {
    return array.indexOf(value, index + 1) < 0;
  });
};

oder in CoffeeScript:

Array.prototype.unique = ->
  this.filter( (value, index, array) ->
    array.indexOf(value, index + 1) < 0
  )
6
Dan Fox

Suche nach eindeutigen Array-Werten in einer einfachen Methode

function arrUnique(a){
  var t = [];
  for(var x = 0; x < a.length; x++){
    if(t.indexOf(a[x]) == -1)t.Push(a[x]);
  }
  return t;
}
arrUnique([1,4,2,7,1,5,9,2,4,7,2]) // [1, 4, 2, 7, 5, 9]
6

Von Shamasis Bhattacharya 's Blog (O (2n) Zeit Komplexität):

Array.prototype.unique = function() {
    var o = {}, i, l = this.length, r = [];
    for(i=0; i<l;i+=1) o[this[i]] = this[i];
    for(i in o) r.Push(o[i]);
    return r;
};

Aus dem Blog von Paul Irish : Verbesserung von JQuery .unique() :

(function($){

    var _old = $.unique;

    $.unique = function(arr){

        // do the default behavior only if we got an array of elements
        if (!!arr[0].nodeType){
            return _old.apply(this,arguments);
        } else {
            // reduce the array to contain no dupes via grep/inArray
            return $.grep(arr,function(v,k){
                return $.inArray(v,arr) === k;
            });
        }
    };
})(jQuery);

// in use..
var arr = ['first',7,true,2,7,true,'last','last'];
$.unique(arr); // ["first", 7, true, 2, "last"]

var arr = [1,2,3,4,5,4,3,2,1];
$.unique(arr); // [1, 2, 3, 4, 5]
5
Frosty Z

Um das Problem anders anzugehen, kann es sinnvoll sein, während des Ladens des Arrays kein Duplikat zu verwenden, wie es von Set object getan wird, aber es ist noch nicht in allen Browsern verfügbar. Es spart Speicher und ist effizienter, wenn Sie den Inhalt oft überprüfen müssen.

Array.prototype.add = function (elem) {
   if (this.indexOf(elem) == -1) {
      this.Push(elem);
   }
}

Probe:

set = [];
[1,3,4,1,2,1,3,3,4,1].forEach(function(x) { set.add(x); });

Gibt dir set = [1,3,4,2]

5
Le Droid

Zauber

a.filter(( t={}, e=>!(t[e]=e in t) )) 

O(n)Leistung ; Wir gehen davon aus, dass sich Ihr Array in a befindet. Erklärung hier (+ Jeppe Verbesserung) 

var a1 = [5,6,0,4,9,2,3,5,0,3,4,1,5,4,9];
var a2 = [[2, 17], [2, 17], [2, 17], [1, 12], [5, 9], [1, 12], [6, 2], [1, 12]];
var a3 = ['Mike', 'Adam','Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl'];

let nd = (a) => a.filter((t={},e=>!(t[e]=e in t))) 


// print
let c= x => console.log(JSON.stringify(x));             
c( nd(a1) );
c( nd(a2) );
c( nd(a3) );

5

Ich fand, dass das Serialisieren ihres Hash-Schlüssels mir half, diese Funktion für Objekte zu nutzen.

Array.prototype.getUnique = function() {
        var hash = {}, result = [], key; 
        for ( var i = 0, l = this.length; i < l; ++i ) {
            key = JSON.stringify(this[i]);
            if ( !hash.hasOwnProperty(key) ) {
                hash[key] = true;
                result.Push(this[i]);
            }
        }
        return result;
    }
3
Jason

Wenn jemand knockoutjs benutzt

ko.utils.arrayGetDistinctValues()

Übrigens haben Sie sich alle ko.utils.array*-Dienstprogramme angesehen.

3

Wenn Sie mit zusätzlichen Abhängigkeiten zufrieden sind oder bereits über eine der Bibliotheken in Ihrer Codebase verfügen, können Sie Duplikate mithilfe von LoDash (oder Underscore) aus einem Array entfernen.

Verwendungszweck

Wenn Sie es noch nicht in Ihrer Codebase haben, installieren Sie es mit npm:

npm install lodash

Dann verwenden Sie es wie folgt:

import _ from 'lodash';
let idArray = _.uniq ([
    1,
    2,
    3,
    3,
    3
]);
console.dir(idArray);

Aus:  

[ 1, 2, 3 ]
3
NikeshPathania

Sie können auch sugar.js verwenden:

[1,2,2,3,1].unique() // => [1,2,3]

[{id:5, name:"Jay"}, {id:6, name:"Jay"}, {id: 5, name:"Jay"}].unique('id') 
  // => [{id:5, name:"Jay"}, {id:6, name:"Jay"}]
3
kornfridge

Es6 basierte Lösung ...

var arr = [2,3,4,2,3,4,2];
const result = [...new Set(arr)];
console.log(result);
2
Vahid Akhtar

Schau dir das an. Jquery bietet die uniq-Methode: https://api.jquery.com/jQuery.unique/

var ids_array = []

$.each($(my_elements), function(index, el) {
    var id = $(this).attr("id")
    ids_array.Push(id)
});

var clean_ids_array = jQuery.unique(ids_array)

$.each(clean_ids_array, function(index, id) {
   elment = $("#" + id)   // my uniq element
   // TODO WITH MY ELEMENT
});
2
ilgam

Ich habe Objektschlüssel verwendet, um ein eindeutiges Array zu erstellen. Ich habe folgendes versucht

function uniqueArray( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });


  return Object.keys(j).map(function(v){
    return j[v];
  });
}   

uniqueArray(["1",1,2,3,4,1,"foo", false, false, null,1]);

Welche gibt ["1", 1, 2, 3, 4, "foo", false, null] zurück

2
rab

Ich denke, dies ist der einfachste Weg, um einen einzigartigen Gegenstand aus einem Array zu erhalten.

var arr = [1,2,4,1,4];
arr = Array.from(new Set(arr))
console.log(arr)
2
Riajul Islam

Wenn Sie die mächtige Methode verkleinern zur Verfügung haben ( ≥ 5.1 ), können Sie Folgendes versuchen:

Array.prototype.uniq = function() {
  return this.reduce(function(sofar, cur) {
    return sofar.indexOf(cur) < 0 ? sofar.concat([cur]) : sofar;
  }, []);
};

Dies ist nicht die effizienteste Implementierung (aufgrund der indexOf-Prüfung, die im schlimmsten Fall die gesamte Liste durchgehen kann). Wenn es auf Effizienz ankommt, können Sie den "Verlauf" von Ereignissen in einer beliebigen Struktur mit wahlfreiem Zugriff (beispielsweise {}) beibehalten und stattdessen diese eingeben. Das ist im Grunde das, was die most most answer tut, also schauen Sie sich das als Beispiel an.

2
Hunan Rostomyan
[...new Set(duplicates)]

Dies ist die einfachste Methode, auf die in MDN Web Docs verwiesen wird.

const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
console.log([...new Set(numbers)]) // [2, 3, 4, 5, 6, 7, 32]
2
SumanP

Das wird funktionieren.

function getUnique(a) {
  var b = [a[0]], i, j, tmp;
  for (i = 1; i < a.length; i++) {
    tmp = 1;
    for (j = 0; j < b.length; j++) {
      if (a[i] == b[j]) {
        tmp = 0;
        break;
      }
    }
    if (tmp) {
      b.Push(a[i]);
    }
  }
  return b;
}
2
Darshan

Tun Sie es mit lodash und der Lambda-Identitätsfunktion, definieren Sie es einfach, bevor Sie Ihr Objekt verwenden

const _ = require('lodash');
...    
_.uniqBy([{a:1,b:2},{a:1,b:2},{a:1,b:3}], v=>v.a.toString()+v.b.toString())
_.uniq([1,2,3,3,'a','a','x'])

und haben:

[{a:1,b:2},{a:1,b:3}]
[1,2,3,'a','x']

(dies ist der einfachste Weg)

2
BazSTR

Aufbauend auf anderen Antworten, folgt hier eine weitere Variante, die ein optionales Flag zur Auswahl einer Strategie erfordert (erstes Auftreten beibehalten oder zuletzt halten):

Ohne Erweiterung Array.prototype 

function unique(arr, keepLast) {
  return arr.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
unique(['a', 1, 2, '1', 1, 3, 2, 6]); // -> ['a', 1, 2, '1', 3, 6]
unique(['a', 1, 2, '1', 1, 3, 2, 6], true); // -> ['a', '1', 1, 3, 2, 6]

Erweitern Array.prototype

Array.prototype.unique = function (keepLast) {
  return this.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
['a', 1, 2, '1', 1, 3, 2, 6].unique(); // -> ['a', 1, 2, '1', 3, 6]
['a', 1, 2, '1', 1, 3, 2, 6].unique(true); // -> ['a', '1', 1, 3, 2, 6]
2
Mrchief

Sie können auch jQuery verwenden

var a = [1,5,1,6,4,5,2,5,4,3,1,2,6,6,3,3,2,4];

// note: jQuery's filter params are opposite of javascript's native implementation :(
var unique = $.makeArray($(a).filter(function(i,itm){ 
    // note: 'index', not 'indexOf'
    return i == $(a).index(itm);
}));

// unique: [1, 5, 6, 4, 2, 3]

Ursprünglich beantwortet unter: jQuery-Funktion, um alle eindeutigen Elemente aus einem Array zu erhalten

2

Für die Deduplizierung ist normalerweise ein Gleichheitsoperator für den angegebenen Typ erforderlich. Die Verwendung einer eq -Funktion hindert uns jedoch daran, eine Set zur effizienten Ermittlung von Duplikaten zu verwenden, da Set auf === zurückfällt. Wie Sie sicher wissen, funktioniert === nicht für Referenztypen. Also sind wir nett, wenn wir nicht weiterkommen, oder?

Der Ausweg besteht einfach darin, eine Transformatorfunktion zu verwenden, mit der wir einen (Referenz-) Typ in etwas verwandeln können, das wir tatsächlich mit einem Set nachschlagen können. Wir könnten zum Beispiel eine Hash-Funktion oder JSON.stringify die Datenstruktur verwenden, wenn sie keine Funktionen enthält.

Oft müssen wir nur auf eine Eigenschaft zugreifen, die wir dann anstelle der Referenz von Object vergleichen können.

Hier sind zwei Kombinatoren, die diese Anforderungen erfüllen:

const dedupeOn = k => xs => {
  const s = new Set();

  return xs.filter(o =>
    s.has(o[k])
      ? null
      : (s.add(o[k]), o[k]));
};

const dedupeBy = f => xs => {
  const s = new Set();

  return xs.filter(x => {
    const r = f(x);
    
    return s.has(r)
      ? null
      : (s.add(r), x);
  });
};

const xs = [{foo: "a"}, {foo: "b"}, {foo: "A"}, {foo: "b"}, {foo: "c"}];

console.log(
  dedupeOn("foo") (xs)); // [{foo: "a"}, {foo: "b"}, {foo: "A"}, {foo: "c"}]

console.log(
  dedupeBy(o => o.foo.toLowerCase()) (xs)); // [{foo: "a"}, {foo: "b"}, {foo: "c"}]

Mit diesen Kombinatoren sind wir äußerst flexibel im Umgang mit allen Arten von Deduplizierungsproblemen. Es ist nicht der schnellste Ansatz, sondern der aussagekräftigste und allgemeinste.

2
bob

ich hatte ein etwas anderes Problem, wo ich Objekte mit doppelten ID-Eigenschaften aus einem Array entfernen musste. das hat funktioniert ..

let objArr = [ { id: '123' }, { id: '123' }, { id: '456' } ];

objArr = objArr.reduce( ( acc, cur ) => [
    ...acc.filter( ( obj ) => obj.id !== cur.id ), cur
], [] );
2
shunryu111

Ich habe eine Lösung, die es6-Methoden zum Reduzieren und Finden von Array-Hilfsmitteln zum Entfernen von Duplikaten verwendet.

let numbers = [2,2,3,3,5,6,6];

const removeDups = array => {
  return array.reduce((acc, inc) => {
    if(!acc.find( i => i === inc)) {
       acc.Push(inc);
    }
     return acc;
  },[]);
}

removeDups(numbers); /// [2,3,5,6]
1
tjacks3
Array.prototype.unique = function() {
    var a = [],k = 0,e;
    for(k=0;e=this[k];k++)
      if(a.indexOf(e)==-1)
           a.Push(e);
    return a;
}
[1,2,3,4,33,23,2,3,22,1].unique(); // return [1,2,3,4,33,23,22]
1
user2718726

Ich weiß, dass dies bereits zu Tode beantwortet wurde ... aber niemand hat die Javascript-Implementierung von linq ..__ erwähnt. Dann kann die .distinct()-Methode verwendet werden - und macht den Code sehr einfach zu lesen.

var Linq = require('linq-es2015');
var distinctValues =  Linq.asEnumerable(testValues)
            .Select(x)
            .distinct()
            .toArray();

var testValues = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1];

var distinctValues = Enumerable.asEnumerable(testValues)
  .distinct()
  .toArray();

console.log(distinctValues);
<script src="https://npmcdn.com/linq-es5/dist/linq.js"></script>

1
pgee70

Erstellen eines Arrays aus eindeutigen Arrays mit Feld [2] als ID:

[ [ '497', 'Q0', 'WTX091-B06-138', '0', '1.000000000', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B09-92', '1', '0.866899288', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B09-92', '2', '0.846036819', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B09-57', '3', '0.835025326', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B43-79', '4', '0.765068215', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B43-56', '5', '0.764211464', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B44-448', '6', '0.761701704', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B44-12', '7', '0.761701704', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B49-128', '8', '0.747434800', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B18-17', '9', '0.746724770', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B19-374', '10', '0.733379549', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B19-344', '11', '0.731421782', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B09-92', '12', '0.726450470', 'GROUP001' ],
  [ '497', 'Q0', 'WTX091-B19-174', '13', '0.712757036', 'GROUP001' ] ]
    .filter((val1, idx1, arr) => !!~val1.indexOf(val1[2]) && 
    !(arr.filter((val2, idx2) => !!~val2.indexOf(val1[2]) && 
idx2 < idx1).length));
1
Ali

Dieses ist nicht rein, es wird das Array modifizieren, aber dies ist das schnellste. Wenn deine schneller ist, dann schreibe bitte in die Kommentare;)

http://jsperf.com/unique-array-webdeb

Array.prototype.uniq = function(){
    for(var i = 0, l = this.length; i < l; ++i){
        var item = this[i];
        var duplicateIdx = this.indexOf(item, i + 1);
        while(duplicateIdx != -1) {
            this.splice(duplicateIdx, 1);
            duplicateIdx = this.indexOf(item, duplicateIdx);
            l--;
        }
    }

    return this;
}

[
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc"
].uniq() //  ["",2,4,"A","abc"]
1
webdeb
var numbers = [1,1,2,3,4,4];

function unique(dupArray) {
    return  dupArray.reduce(function (previous, num){

        if (previous.find(function(item){
            return item == num;
        })) {
            return previous;
        } else {
            previous.Push(num);
            return previous;
        }
    }, [])
}

var check = unique(numbers);
console.log(check);
1
Junaid Khan

Noch eine andere Lösung für den Stapel.

Ich musste vor kurzem eine sortierte Liste eindeutig machen, und ich tat es mit einem Filter, der das vorherige Element in einem Objekt wie diesem verfolgt:

uniqueArray = sortedArray.filter(function(e) { 
    if(e==this.last) 
      return false; 
    this.last=e; return true;  
  },{last:null});
1
pix

Mit Sets können Sie jetzt Duplikate entfernen und zurück in das Array konvertieren.

var names = ["Mike","Matt","Nancy", "Matt","Adam","Jenny","Nancy","Carl"];

console.log([...new Set(names)])
1
Krishnadas PC

Sie können Ramda.js verwenden, eine funktionale Javascript-Bibliothek, um dies zu tun:

var unique = R.uniq([1, 2, 1, 3, 1, 4])
console.log(unique)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

1
Morris S

Dieses Skript modifiziert das Array und filtert doppelte Werte aus. Es funktioniert mit Zahlen und Strings.

https://jsfiddle.net/qsdL6y5j/1/

    Array.prototype.getUnique = function () {
        var unique = this.filter(function (elem, pos) {
            return this.indexOf(elem) == pos;
        }.bind(this));
        this.length = 0;
        this.splice(0, 0, unique);
    }

    var duplicates = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    duplicates.getUnique();
    alert(duplicates);

Bei dieser Version können Sie stattdessen ein neues Array mit eindeutigem Wert zurückgeben, wobei das Original beibehalten wird (übergeben Sie einfach "true").

https://jsfiddle.net/dj7qxyL7/

    Array.prototype.getUnique = function (createArray) {
        createArray = createArray === true ? true : false;
        var temp = JSON.stringify(this);
        temp = JSON.parse(temp);
        if (createArray) {
            var unique = temp.filter(function (elem, pos) {
                return temp.indexOf(elem) == pos;
            }.bind(this));
            return unique;
        }
        else {
            var unique = this.filter(function (elem, pos) {
                return this.indexOf(elem) == pos;
            }.bind(this));
            this.length = 0;
            this.splice(0, 0, unique);
        }
    }

    var duplicates = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    console.log('++++ ovveride')
    duplicates.getUnique();
    console.log(duplicates);
    console.log('++++ new array')
    var duplicates2 = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    var unique = duplicates2.getUnique(true);
    console.log(unique);
    console.log('++++ original')
    console.log(duplicates2);

Browser support:

Feature Chrome  Firefox (Gecko)     Internet Explorer   Opera   Safari
Basic support   (Yes)   1.5 (1.8)   9                   (Yes)   (Yes)
1
GibboK

Die Version, die Selector akzeptiert, sollte ziemlich schnell und prägnant sein:

function unique(xs, f) {
  var seen = {};
  return xs.filter(function(x) {
    var fx = (f && f(x)) || x;
    return !seen[fx] && (seen[fx] = 1);
  });
}
1
Grozz

Dies ist eine ES6-Funktion, die Duplikate aus einem Array von Objekten entfernt und nach der angegebenen Objekteigenschaft filtert

function dedupe(arr = [], fnCheck = _ => _) {
  const set = new Set();
  let len = arr.length;

  for (let i = 0; i < len; i++) {
    const primitive = fnCheck(arr[i]);
    if (set.has(primitive)) {
      // duplicate, cut it
      arr.splice(i, 1);
      i--;
      len--;
    } else {
      // new item, add it
      set.add(primitive);
    }
  }

  return arr;
}

const test = [
    {video:{slug: "a"}},
    {video:{slug: "a"}},
    {video:{slug: "b"}},
    {video:{slug: "c"}},
    {video:{slug: "c"}}
]
console.log(dedupe(test, x => x.video.slug));

// [{video:{slug: "a"}}, {video:{slug: "b"}}, {video:{slug: "c"}}]
1
Andrei

Wenn Sie eindeutige Werte sagen, bedeutet das für mich Werte, die nur einmal im Datensatz vorkommen.

Im Folgenden wird das Werte-Array gefiltert, wobei überprüft wird, ob der erste und der letzte Index eines bestimmten Werts gleich sind. Wenn der Index gleich ist, muss der Wert nur einmal vorkommen.

var values = [1, 2, 3, 4, 5, 2, 4, 6, 2, 1, 5];

var unique = values.filter(function(value) {
  return values.indexOf(value) === values.lastIndexOf(value);
});

console.log(unique); // [3, 6]

Basierend auf Rückmeldungen, die ich falsch verstanden habe, folgt hier ein alternativer Ansatz, der eindeutige, nicht doppelte Werte aus dem Werte-Array liefert.

var values = [1, 2, 3, 4, 5, 2, 4, 6, 2, 1, 5];
var unique = values.reduce(function(unique, value) {
  return unique.indexOf(value) === -1 ? unique.concat([value]) : unique;
}, []);

console.log(unique); // [1, 2, 3, 4, 5, 6]

1
fubar

Ähnlich der @ sergeyz-Lösung, jedoch kompakter durch Verwendung von Kurzformaten wie Pfeilfunktionen und array.includes. Warnung: JSlint wird sich wegen der Verwendung des logischen oder und des Kommas beschweren. (obwohl immer noch perfekt gültiges Javascript)

my_array.reduce((a,k)=>(a.includes(k)||a.Push(k),a),[])
1
John Smith

Viele Leute haben bereits erwähnt, dass sie ...

[...new Set(arr)];

Und das ist eine großartige Lösung, aber ich bevorzuge eine Lösung, die mit .filter funktioniert. Meiner Meinung nach ist Filter ein natürlicherer Weg, um eindeutige Werte zu erhalten. Duplikate werden effektiv entfernt, und das Entfernen von Elementen aus einem Array ist genau das, wofür Filter gedacht sind. Sie können auch .map, .reduce und andere .filter Anrufe verketten. Ich habe diese Lösung entwickelt ...

const unique = () => {
  let cache;  
  return (elem, index, array) => {
    if (!cache) cache = new Set(array);
    return cache.delete(elem);
  };
};

myArray.filter(unique());

Die Einschränkung ist, dass Sie eine Schließung benötigen, aber ich denke, dies ist ein angemessener Kompromiss. In Bezug auf die Leistung ist es performanter als die anderen Lösungen, die ich gesehen habe und die .filter verwenden, aber schlechter als [...new Set(arr)].

Siehe auch mein Github-Paket youneek

0
Nizmox

Die obige Objektantwort scheint für mich in meinem Anwendungsfall mit Objekten nicht zu funktionieren.

Ich habe es wie folgt geändert:

var j = {};

this.forEach( function(v) {
   var typ = typeof v;
   var v = (typ === 'object') ? JSON.stringify(v) : v;

   j[v + '::' + typ] = v;
});

return Object.keys(j).map(function(v){
  if ( v.indexOf('::object') > -1 ) {
    return JSON.parse(j[v]);
  }

  return j[v];
});

Dies scheint nun korrekt für Objekte, Arrays, Arrays mit gemischten Werten, Booleans usw. zu funktionieren.

0
user3591464

Diese Lösung sollte sehr schnell sein und funktioniert in vielen Fällen.

  1. Konvertieren Sie die indizierten Arrayelemente in Objektschlüssel
  2. Verwenden Sie die Funktion Object.keys

    var indexArray = ["hi","welcome","welcome",1,-9];
    var keyArray = {};
    indexArray.forEach(function(item){ keyArray[item]=null; });
    var uniqueArray = Object.keys(keyArray);
    
0

Manchmal muss ich eindeutige Vorkommen aus einer Reihe von Objekten abrufen. Lodash scheint ein netter Helfer zu sein, aber ich glaube nicht, dass das Filtern eines Arrays das Hinzufügen einer Abhängigkeit zu einem Projekt rechtfertigt.

Nehmen wir an, der Vergleich zweier Objekte ergibt sich aus dem Vergleich einer Eigenschaft, beispielsweise einer ID.

const a = [{id: 3}, {id: 4}, {id: 3}, {id: 5}, {id: 5}, {id: 5}];

Da wir alle Snippets mit einer Zeile lieben, können Sie dies folgendermaßen tun:

a.reduce((acc, curr) => acc.find(e => e.id === curr.id) ? acc : [...acc, curr], [])

0

Wenn Sie über ein Array von Objekten verfügen, und Sie eine uniqueBy-Funktion wünschen, z. B. durch ein ID-Feld: 

function uniqueBy(field, arr) {
   return arr.reduce((acc, curr) => {
     const exists = acc.find(v => v[field] === curr[field]);
     return exists ? acc : acc.concat(curr);
   }, [])
}
0
Ben

Ich habe ein einfaches Beispiel, in dem wir Objekte aus dem Array entfernen können, die eine wiederholte ID in Objekten haben.

  let data = new Array({id: 1},{id: 2},{id: 3},{id: 1},{id: 3});
  let unique = [];
  let tempArr = [];
  console.log('before', data);
  data.forEach((value, index) => {
    if (unique.indexOf(value.id) === -1) {
      unique.Push(value.id);
    } else {
      tempArr.Push(index);    
    }
  });
  tempArr.reverse();
  tempArr.forEach(ele => {
    data.splice(ele, 1);
  });
  console.log(data);
0
Shridhar Sagari

Wenn die Reihenfolge nicht wichtig ist, können wir einen Hash erstellen und die Schlüssel für ein eindeutiges Array erhalten.

var ar = [1,3,4,5,5,6,5,6,2,1];
var uarEle = {};
links.forEach(function(a){ uarEle[a] = 1; });
var uar = keys(uarEle)

sie werden die einzigartigen Array-Elemente haben.

0
Kishore Relangi

Noch eine Antwort, nur weil ich eine für meinen speziellen Anwendungsfall geschrieben habe. Ich habe das Array ohnehin sortiert, und da ich sortieren kann, kann ich das zum Deduplizieren verwenden.

Beachten Sie, dass meine Sortierung sich auf meine spezifischen Datentypen bezieht. Je nach Art der Elemente benötigen Sie möglicherweise eine andere Sortierung.

var sortAndDedup = function(array) {
  array.sort(function(a,b){
    if(isNaN(a) && isNaN(b)) { return a > b ? 1 : (a < b ? -1 : 0); }
    if(isNaN(a)) { return 1; }
    if(isNaN(b)) { return -1; }
    return a-b;
  });

  var newArray = [];
  var len = array.length;
  for(var i=0; i<len; i++){
    if(i === 0 || array[i] != array[i-1]){
      newArray.Push(array[i]);
    }
  }
};
0
PaulL

Verwenden Sie .toString () für Zeichenfolgen.

var givenvalues = [1,2,3,3,4,5,6];
var values = [];
for(var i=0; i<givenvalues.length; i++)
{
    if(values.indexOf(givenvalues[i]) == -1)
    {
        values[values.length] = givenvalues[i];
    }
}
0
Phani CR

Ich habe mir Joeytje50s Code über jsperf angesehen, der eine Reihe von Alternativen verglichen hat. Sein Code hatte viele kleinere Tippfehler, was sich auf die Leistung und die Richtigkeit auswirkte.

Noch wichtiger ist, dass er auf einem sehr kleinen Array testet. Ich habe ein Array mit 1000 ganzen Zahlen erstellt. Jede ganze Zahl war 100-mal eine zufällige ganze Zahl zwischen 0 und 1000. Dies ergibt im Durchschnitt etwa 1000/e = 368 Duplikate. Die Ergebnisse sind um jsperf .

Dies ist ein viel realistischeres Szenario, in dem Effizienz erforderlich sein könnte. Diese Änderungen haben dramatische Änderungen in den Behauptungen zur Folge (insbesondere der als am schnellsten angekündigte Code ist bei weitem nicht so schnell). Die offensichtlichen Gewinner sind dort, wo Hashtechniken eingesetzt werden, wobei der beste der beste ist

Array.prototype.getUnique3 = function(){
   var u = Object.create(null), a = [];
   for(var i = 0, l = this.length; i < l; ++i){
      if(this[i] in u) continue;
      a.Push(this[i]);
      u[this[i]] = 1;
   }
   return a.length;
}
0
Roobie Nuby
var a = [1,4,2,7,1,5,9,2,4,7,2]
var b = {}, c = {};
var len = a.length;
for(var i=0;i<len;i++){
  a[i] in c ? delete b[a[i]] : b[a[i]] = true;
  c[a[i]] = true;
} 

// b contains all unique elements
0
rajesh

Sie können die Hilfsfunktionen von Arrays "less" () und einige () verwenden, um Ihr Ergebnis zu erzielen. Überprüfen Sie mein Code-Snippet:

var arrayWithDuplicates = [0, 0, 1, 2, 3, 3, 4, 4, 'a', 'a', '', '', null, null];

var arrayWithUniqueValues = arrayWithDuplicates
                            .reduce((previous, item) => {
                                if(!previous.some(element => element === item)) {
                                    previous.Push(item)
                                }
                                return previous;
                            }, []);

console.log('arrayWithUniqueValues', arrayWithUniqueValues)

Undefinierte Werte und Nullwerte werden herausgefiltert, da Sie sie meistens nicht benötigen.

const uniques = myArray.filter(e => e).filter((e, i, a) => a.indexOf(e) === i);

oder

const uniques = [...new Set(myArray.filter(e => e))];
0
LEMUEL ADANE