Duplikate aus einem Array herausfiltern und nur eindeutige Werte zurückgeben

82658
GibboK

Ich habe das folgende Skript, das Duplikate filtert und nur eindeutige Werte für ein Array zurückgibt. Beim Übergeben falseoder Nicht-Überschreiben des "ursprünglichen" Arrays wird trueein neues Array mit eindeutigen Werten erstellt und stattdessen zurückgegeben.

Das Skript sollte nur mit Zahlen und Strings funktionieren.

Ich würde gerne wissen:

  • Wenn es möglich ist, den Code für maximale Leistung und wie zu optimieren,
  • Wenn es möglich ist, die Logik auf alternative Weise zu verbessern oder zu schreiben createArray, ist dies möglicherweise eine bessere Methode in Bezug auf die Codewiederholung.

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);
Antworten
7
Möglicherweise interessieren Sie sich für: http://codereview.stackexchange.com/questions/57581/how-can-i-quickly-find-unique-list-items und http://codereview.stackexchange.com/questions/14741/ Optimieren-Refactor-Javascript-Unique-Array-Funktion. Emily L. vor 5 Jahren 2
Obwohl dies offensichtlich für die Übung durchgeführt wurde, kann es erwähnenswert sein, dass [lodash] (https://lodash.com/docs#uniq) dies bereits in der Form `_.uniq (array)` implementiert hat Dan Pantry vor 5 Jahren 0
Gibt es einen Grund, warum "[... new Set (source)]" Ihre Anforderungen nicht erfüllen würde? Iiridayn vor 3 Jahren 0

2 Antworten auf die Frage

10
elclanrs

Wenn es möglich ist, die Logik für createArray auf alternative Weise zu verbessern oder zu schreiben, ist dies möglicherweise eine bessere Methode für die Codewiederholung.

Warum die Möglichkeit geben, das Array zu mutieren? Die meisten Array-Methoden geben ein neues Array zurück, einschließlich filter, sodass es in Ihrem Code überflüssig erscheint, da Sie sowieso ein neues Array erhalten. Das Array nicht zu mutieren ist in der Regel das Richtige. In jedem Fall ist die Verwendung von JSON zum Klonen eines Arrays sehr ineffizient, wenn Sie nur noch etwas benötigen var copy = array.slice(). und eine rekursive Lösung für verschachtelte Arrays. Wenn Sie diese ungewöhnliche Anforderung loswerden und eine eigene Funktion erstellen, anstatt den Prototyp zu erweitern, bleiben Sie bei dem, was uniquewirklich ist:

var unique = function(xs) {
  return xs.filter(function(x, i) {
    return xs.indexOf(x) === i
  })
}

Wenn es möglich ist, den Code für maximale Leistung und wie zu optimieren

Wenn Sie sich nur mit Dingen befassen, die ordnungsgemäß festgelegt werden können, wie Zahlen und offensichtlich Zeichenfolgen, können Sie die Leistung verbessern, indem Sie ein einfaches Objekt verwenden, um bereits gesehene Elemente zu verfolgen:

var unique = function(xs) {
  var seen = {}
  return xs.filter(function(x) {
    if (seen[x])
      return
    seen[x] = true
    return x
  })
}

Obwohl dies hielte 1und '1'ein Duplikat zu sein.

Würden Sie mir vorschlagen, eine Prototyperweiterung anstelle einer "Utility" -Funktion zu haben? Vielen Dank für Ihre Zeit, ich schätze es sehr. GibboK vor 5 Jahren 0
Ich würde vorschlagen, native Prototypen niemals zu erweitern. Aber es macht die Funktion auch weniger wiederverwendbar, wenn Sie sie als Funktion weitergeben möchten, statt einen Punkt in einem Array aufzurufen, wird sie mit `Function.prototype.call.bind (Array.prototype.unique) (xs) zum Durcheinander ) `. Nicht so gut für die Komposition. elclanrs vor 5 Jahren 3
2
janos

Neben dem hervorragenden Testbericht von @elclanrs gibt es ein paar kleinere Probleme mit dem Codierungsstil, die ich ebenfalls korrigieren möchte.

An Stelle von:

    createArray = createArray === true ? true : false;

Sie können (und sollten) einfach folgendes schreiben:

    createArray = createArray === true;

Und da die tempVariable nur verwendet wird, wenn createArraywahr ist, sollten Sie diese innerhalb von verschieben if (createArray) , um sinnlose Ausführungen zu vermeiden.