544 Stimmen

Alle nicht eindeutigen Werte (d.h.: doppeltes/mehrmaliges Vorkommen) in einem Array ermitteln

Ich muss ein JavaScript-Array überprüfen, um festzustellen, ob es irgendwelche doppelten Werte gibt. Was ist der einfachste Weg, dies zu tun? Ich brauche nur zu finden, was die doppelten Werte sind - ich brauche nicht wirklich ihre Indizes oder wie oft sie dupliziert werden.

Ich weiß, dass ich das Array in einer Schleife durchlaufen und alle anderen Werte auf eine Übereinstimmung prüfen kann, aber es scheint, als sollte es einen einfacheren Weg geben.

Ähnliche Frage:

29 Stimmen

Es scheint jahrelang Verwirrung darüber zu herrschen, was diese Frage bedeutet. Ich musste wissen, welche Elemente in dem Array doppelt vorhanden waren: "Ich muss nur herausfinden, welche Werte doppelt vorhanden sind". Die richtige Antwort sollte NICHT die Duplikate aus dem Array entfernen. Das ist genau das Gegenteil von dem, was ich wollte: eine Liste der Duplikate, nicht eine Liste der eindeutigen Elemente.

0 Stimmen

github.com/lodash/lodash/issues/4852#issuecomment-666366511 Ich würde dies als Antwort hinzufügen, aber angesichts der Länge der Antworten würde es nie gesehen werden

30voto

karim79 Punkte 333786

Sie können diese Funktion hinzufügen oder sie abändern und dem Array-Prototyp von Javascript hinzufügen:

Array.prototype.unique = function () {
    var r = new Array();
    o:for(var i = 0, n = this.length; i < n; i++)
    {
        for(var x = 0, y = r.length; x < y; x++)
        {
            if(r[x]==this[i])
            {
                alert('this is a DUPE!');
                continue o;
            }
        }
        r[r.length] = this[i];
    }
    return r;
}

var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,9];
var unique = arr.unique();
alert(unique);

0 Stimmen

Dies ist die beste Lösung, aber seien Sie vorsichtig, wenn Sie es zum Array-Prototyp hinzufügen, da dies den IE durcheinander bringt, wenn Sie die Werte in einer Schleife durchlaufen.

0 Stimmen

@RoyTinker perl unterstützt sie auch, aber ich hatte keine Ahnung, dass javascript das tut

3 Stimmen

Erfüllt nicht den Wunsch des Auftraggebers, die Duplikate zurückzugeben.

28voto

AKTUALISIERT: Im Folgenden wird eine optimierte kombinierte Strategie verwendet. Sie optimiert die primitiven Suchvorgänge, um von der O(1)-Suchzeit des Hashes zu profitieren (die unique für ein Array von Primitiven ist O(n)). Die Suche nach Objekten wird optimiert, indem Objekte mit einer eindeutigen Kennung versehen werden, während sie durchlaufen werden, so dass die Identifizierung doppelter Objekte ebenfalls O(1) pro Objekt und O(n) für die gesamte Liste ist. Die einzige Ausnahme sind eingefrorene Objekte, aber die sind selten und ein Fallback wird mit einem Array und indexOf bereitgestellt.

var unique = function(){
  var hasOwn = {}.hasOwnProperty,
      toString = {}.toString,
      uids = {};

  function uid(){
    var key = Math.random().toString(36).slice(2);
    return key in uids ? uid() : uids[key] = key;
  }

  function unique(array){
    var strings = {}, numbers = {}, others = {},
        tagged = [], failed = [],
        count = 0, i = array.length,
        item, type;

    var id = uid();

    while (i--) {
      item = array[i];
      type = typeof item;
      if (item == null || type !== 'object' && type !== 'function') {
        // primitive
        switch (type) {
          case 'string': strings[item] = true; break;
          case 'number': numbers[item] = true; break;
          default: others[item] = item; break;
        }
      } else {
        // object
        if (!hasOwn.call(item, id)) {
          try {
            item[id] = true;
            tagged[count++] = item;
          } catch (e){
            if (failed.indexOf(item) === -1)
              failed[failed.length] = item;
          }
        }
      }
    }

    // remove the tags
    while (count--)
      delete tagged[count][id];

    tagged = tagged.concat(failed);
    count = tagged.length;

    // append primitives to results
    for (i in strings)
      if (hasOwn.call(strings, i))
        tagged[count++] = i;

    for (i in numbers)
      if (hasOwn.call(numbers, i))
        tagged[count++] = +i;

    for (i in others)
      if (hasOwn.call(others, i))
        tagged[count++] = others[i];

    return tagged;
  }

  return unique;
}();

Wenn Sie ES6 Collections zur Verfügung haben, gibt es eine viel einfachere und deutlich schnellere Version. (Shim für IE9+ und andere Browser hier: https://github.com/Benvie/ES6-Harmony-Collections-Shim )

function unique(array){
  var seen = new Set;
  return array.filter(function(item){
    if (!seen.has(item)) {
      seen.add(item);
      return true;
    }
  });
}

0 Stimmen

Warum sollten Sie eine Frage beantworten, die bereits vor über 2 Jahren gelöst wurde?

3 Stimmen

Ich war dabei, eine andere Frage zu beantworten, und habe offenbar versehentlich auf einen Link zu dieser Frage geklickt und sie als Duplikat bezeichnet. Ich bearbeite meine Sachen sehr oft.

0 Stimmen

24voto

var a = ["a","a","b","c","c"];

a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})

0 Stimmen

Das scheint zu funktionieren, aber Sie sollten vielleicht einen Text hinzufügen, der beschreibt, wie es funktioniert.

4 Stimmen

Funktioniert nicht, wenn es mehr als 2 Vorkommen eines doppelten Wertes gibt.

1 Stimmen

Das ist elegant und einfach. Ich liebe es. Für diejenigen, die herausfinden wollen, wie sie funktionieren, habe ich einen Gist erstellt, der zeigt, wie man Duplikate anzeigt und Duplikate eliminiert. Siehe hier: gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b

23voto

vsync Punkte 101339

Finden. nicht einmalig Werte aus 3 Arrays (oder mehr):

ES2015

//                             
var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
    arr2 = [1,2,511,12,50],
    arr3 = [22,0],
    merged,
    nonUnique;

// Combine all the arrays to a single one
merged = arr.concat(arr2, arr3)

// create a new (dirty) Array with only the non-unique items
nonUnique = merged.filter((item,i) => merged.includes(item, i+1))

// Cleanup - remove duplicate & empty items items 
nonUnique = [...new Set(nonUnique)]

console.log(nonUnique)

PRE-ES2015:

In dem folgenden Beispiel habe ich eine überlagerte unique Methode über der Array Prototyp und ermöglicht den Zugang von überall her und hat mehr "deklarativ" Syntax. Ich empfehle diesen Ansatz bei großen Projekten nicht, da es sehr wohl zu Kollisionen mit einer anderen Methode mit demselben benutzerdefinierten Namen kommen kann.

Array.prototype.unique = function () {
    var arr = this.sort(), i=arr.length; // input must be sorted for this to work
    while(i--)
      arr[i] === arr[i-1] && arr.splice(i,1) // remove duplicate item
    return arr
}

Array.prototype.nonunique = function () {
    var arr = this.sort(), i=arr.length, res = []; // input must be sorted for this to work
    while(i--)
      arr[i] === arr[i-1] && (res.indexOf(arr[i]) == -1) && res.push(arr[i]) 
    return res
}

//                             
var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
    arr2 = [1,2,511,12,50],
    arr3 = [22,0],
    // merge all arrays & call custom Array Prototype - "unique"
    unique = arr.concat(arr2, arr3).unique(),
    nonunique = arr.concat(arr2, arr3).nonunique()

console.log(unique)     // [1,12,2,22,3,4,5,50,511,6,7,8]
console.log(nonunique)  // [1,12,2,22,3,4,5,50,511,6,7,8]

0 Stimmen

+1, weil es definitiv lesbarer ist der Code mit Array.indexOf, aber leider scheint es langsamer als mit einer einfachen verschachtelten Schleife. Selbst auf Browsern, die Array.indexOf nayively wie FF implementiert. Plz, Werfen Sie einen Blick auf diese Tests habe ich hier: jsperf.com/array-unique2 und teilen Sie mir Ihre Meinung mit.

0 Stimmen

@shekhardesigner - aktualisierte Antwort. "r" ist das Array, in dem Sie suchen

0 Stimmen

@vsync musste ich initialisieren, var r = []; um Ihren Code zum Laufen zu bringen. Und arbeitete wie Charme.

22voto

Daniel Beardsley Punkte 19137

Damit sollten Sie bekommen, was Sie wollen, nur die Duplikate.

function find_duplicates(arr) {
  var len=arr.length,
      out=[],
      counts={};

  for (var i=0;i<len;i++) {
    var item = arr[i];
    counts[item] = counts[item] >= 1 ? counts[item] + 1 : 1;
    if (counts[item] === 2) {
      out.push(item);
    }
  }

  return out;
}

find_duplicates(['one',2,3,4,4,4,5,6,7,7,7,'pig','one']); // -> ['one',4,7] in no particular order.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X