Ruft alle nicht eindeutigen Werte (dh Duplikat / mehr als ein Vorkommen) in einem Array ab


418

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

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

Ähnliche Frage:


22
Es scheint Jahre der Verwirrung darüber zu geben, was diese Frage stellt. Ich musste wissen, welche Elemente im Array dupliziert wurden: "Ich muss nur die duplizierten Werte finden". Die richtige Antwort sollte KEINE Duplikate aus dem Array entfernen. Das ist das Gegenteil von dem, was ich wollte: eine Liste der Duplikate, keine Liste eindeutiger Elemente.
Scott Saunders

Antworten:


301

Sie können das Array sortieren und dann durchlaufen und dann prüfen, ob der nächste (oder vorherige) Index mit dem aktuellen Index übereinstimmt. Vorausgesetzt, Ihr Sortieralgorithmus ist gut, sollte dieser Wert kleiner als O (n 2 ) sein:

const findDuplicates = (arr) => {
  let sorted_arr = arr.slice().sort(); // You can define the comparing function here. 
  // JS by default uses a crappy string compare.
  // (we use slice to clone the array so the
  // original array won't be modified)
  let results = [];
  for (let i = 0; i < sorted_arr.length - 1; i++) {
    if (sorted_arr[i + 1] == sorted_arr[i]) {
      results.push(sorted_arr[i]);
    }
  }
  return results;
}

let duplicatedArray = [9, 9, 111, 2, 3, 4, 4, 5, 7];
console.log(`The duplicates in ${duplicatedArray} are ${findDuplicates(duplicatedArray)}`);

Für den Fall, dass Sie als Funktion für Duplikate zurückkehren sollen. Dies gilt für ähnliche Fälle.

Referenz: https://stackoverflow.com/a/57532964/8119511


10
"Vorausgesetzt, Ihr Sortieralgorithmus ist gut, sollte dieser Wert kleiner als O ^ 2 sein." Insbesondere könnte es O (n * log (n)) sein.
ESRogs

83
Dieses Skript funktioniert nicht so gut mit mehr als 2 Duplikaten (zBarr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
Mottie

7
@swilliams Ich glaube nicht, dass diese Richtlinien etwas über die Nichtverwendung aussagen i++. Stattdessen sagen sie, nicht zu schreiben j = i + +j. Zwei verschiedene Dinge IMHO. Ich finde i += 1es verwirrender als das Einfache und Schöne i++:)
Danilo Bargen

34
-1 Diese Antwort ist auf vielen Ebenen falsch. Zuallererst var sorted_arr = arr.sort()ist es nutzlos: arr.sort()mutiert das ursprüngliche Array (was ein Problem für sich ist). Dadurch wird auch ein Element verworfen. (Führen Sie den obigen Code aus. Was passiert mit 9?) Cc @dystroy Eine sauberere Lösung wäreresults = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
NullUserException

24
Jeder: In der Frage wird darum gebeten, die doppelten Werte anzuzeigen und nicht zu entfernen. Bitte bearbeiten / brechen Sie den Code nicht, um ihn dazu zu bringen, etwas zu tun, was er nicht versucht. Die Warnung sollte die Werte anzeigen, die dupliziert wurden.
Scott Saunders

205

Wenn Sie die Duplikate entfernen möchten, versuchen Sie diese großartige Lösung:

function eliminateDuplicates(arr) {
  var i,
      len = arr.length,
      out = [],
      obj = {};

  for (i = 0; i < len; i++) {
    obj[arr[i]] = 0;
  }
  for (i in obj) {
    out.push(i);
  }
  return out;
}

Quelle: http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates/


18
Das ist guter Code, aber leider macht er nicht das, wonach ich frage.
Scott Saunders

67
Der obige Code (der mir gehört - das ist mein Blog) bringt Sie ziemlich nahe. Ein kleiner Tweak und du bist da. Zunächst können Sie sehen, ob arr.length und out.length gleich sind. Wenn sie gleich sind, gibt es keine doppelten Elemente. Aber du willst ein bisschen mehr. Wenn Sie die Dupes "fangen" möchten, überprüfen Sie, ob die Länge des Arrays nach der Zeile obj [arr [i]] = 0 zunimmt. Schlau, was? :-) Danke für die schönen Worte, Raphael Montanaro.
Nosredna

6
@MarcoDemaio: Äh, nein, warum sollte der Code nicht mit Leerzeichen funktionieren? Sie können einen Eigenschaftsnamen beliebig eingeben - Sie können jedoch nicht die Punktsyntax verwenden, um auf Leerzeichen zuzugreifen (oder auf Requisiten mit verschiedenen anderen Zeichen, die das Parsen unterbrechen würden).
Gijs

4
@ Gijs: +1 du hast recht. Ich wusste es nicht. Aber es funktioniert immer noch nicht, wenn es sich um ein Array von Objekten handelt.
Marco Demaio

3
Dieser Algorithmus hat auch den Nebeneffekt, dass ein sortiertes Array zurückgegeben wird, das möglicherweise nicht Ihren Wünschen entspricht.
asymmetrisch

165

Dies ist meine Antwort aus dem doppelten Thread (!):

Beim Schreiben dieses Eintrags 2014 waren alle Beispiele for-Schleifen oder jQuery. Javascript hat dafür die perfekten Werkzeuge: Sortieren, Zuordnen und Reduzieren.

Suchen Sie nach doppelten Elementen

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

var uniq = names
  .map((name) => {
    return {
      count: 1,
      name: name
    }
  })
  .reduce((a, b) => {
    a[b.name] = (a[b.name] || 0) + b.count
    return a
  }, {})

var duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1)

console.log(duplicates) // [ 'Nancy' ]

Mehr funktionale Syntax:

@ Dmytro-Laptin wies darauf hin, dass ein Code-Code entfernt werden muss. Dies ist eine kompaktere Version desselben Codes. Verwenden einiger ES6-Tricks und Funktionen höherer Ordnung:

const names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

const count = names =>
  names.reduce((a, b) => ({ ...a,
    [b]: (a[b] || 0) + 1
  }), {}) // don't forget to initialize the accumulator

const duplicates = dict =>
  Object.keys(dict).filter((a) => dict[a] > 1)

console.log(count(names)) // { Mike: 1, Matt: 1, Nancy: 2, Adam: 1, Jenny: 1, Carl: 1 }
console.log(duplicates(count(names))) // [ 'Nancy' ]


1
Dies ist die Art von Lösung, nach der ich gesucht habe. Wenn ich ein Dutzend For-Loops haben wollte, ist das ziemlich einfach zu schreiben. Das Schlüsselwort im OP war "effizient".
Josh

@ChristianLandgren, wo wird die Variable 'dict' deklariert? Vielleicht sollte stattdessen 'count' verwendet werden?
Dmytro Laptin

4
Bitte behalten Sie Ihre irreführende Meinung für sich (-1 für Arroganz). Ich persönlich habe es satt, dass Leute "kurz" und "effizient" verwechseln und Einzeiler posten, ohne die Leistungen in Frage zu stellen. Kurzprogramme und moderne JS sind von Natur aus NICHT besser. Typischer Missbrauch des Wortes "effizient" hier . Typischer naiver Glaube hier (siehe folgende Kommentare). Demo hier .
Blatt

1
@leaf - bitte behalten Sie Ihre Vorschläge zu Ihren eigenen Antworten. Die von Ihnen bearbeitete Lösung ist nicht lesbar, sie ist möglicherweise performant (wahrscheinlich nicht), aber trotzdem - Lesbarkeit ist meiner Meinung nach oft wichtiger als Leistung. Aber am wichtigsten - entfernen Sie nicht den Code eines anderen, um ihn ohne Grund durch Ihren zu ersetzen.
Christian Landgren

1
Unterschiedliche Antworten, ja, unterschiedliche Meinungen, das glaube ich nicht.
Blatt

64

Suchen Sie nach doppelten Werten in einem Array

Dies sollte eine der kürzesten Möglichkeiten sein, um doppelte Werte in einem Array zu finden. Wie vom OP ausdrücklich gefordert , werden Duplikate nicht entfernt, sondern gefunden .

var input = [1, 2, 3, 1, 3, 1];

var duplicates = input.reduce(function(acc, el, i, arr) {
  if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;
}, []);

document.write(duplicates); // = 1,3 (actual array == [1, 3])

Dies erfordert keine Sortierung oder ein Framework von Drittanbietern. Es werden auch keine manuellen Schleifen benötigt. Es funktioniert mit jedem Wert, den indexOf () (oder um es klarer zu sagen : der strenge Vergleichsoperator ) unterstützt.

Aufgrund von redu () und indexOf () benötigt es mindestens IE 9.


7
ES6 Pfeil / einfache / reine Version:const dupes = items.reduce((acc, v, i, arr) => arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc, [])
ZephDavies

30

Sie können diese Funktion hinzufügen oder optimieren und zum 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);

Dies ist die beste Lösung, aber achten Sie darauf, sie nicht zum Array-Prototyp hinzuzufügen, da dies den IE beim Durchlaufen der Werte durcheinander bringt.
Sampsa Suoninen

@ RoyTinker Perl unterstützt sie auch, aber ich hatte keine Ahnung, dass Javascript es tat
Luke H

1
Wenn Sie nicht das tun, was das OP verlangt hat, geben Sie die Duplikate zurück.
RWC

27

AKTUALISIERT: Im Folgenden wird eine optimierte kombinierte Strategie verwendet. Es optimiert primitive Suchvorgänge, um von der Suchzeit für Hash O (1) zu profitieren (die Ausführung uniqueauf einem Array von Grundelementen ist O (n)). Objektsuchen werden optimiert, indem Objekte beim Durchlaufen mit einer eindeutigen ID versehen werden, sodass die Identifizierung doppelter Objekte auch O (1) pro Element und O (n) für die gesamte Liste beträgt. Die einzige Ausnahme sind Elemente, die eingefroren sind, aber diese sind selten, und ein Fallback wird mithilfe eines Arrays 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 über ES6-Sammlungen verfügen, gibt es eine viel einfachere und wesentlich 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;
    }
  });
}

Ja wirklich? Warum eine Frage beantworten, die vor über 2 Jahren gelöst wurde?
Rene Pot

3
Ich beantwortete eine andere Frage und klickte anscheinend versehentlich auf jemanden, der mit dieser verknüpft war, und nannte sie ein Duplikat. Am Ende klonte ich meine Antwort und verwirrte mich selbst. Ich bearbeite meine Sachen viel.


16
Ich finde es schön mit verschiedenen Lösungen. Es spielt keine Rolle, dass das Thema alt und gelöst ist, da es immer noch möglich ist, verschiedene Möglichkeiten dafür zu finden. Es ist ein typisches Problem in der Informatik.
Emil Vikström

Vielleicht möchten Sie erwähnen, dass dies auf ES5-Array-Methoden beruht, die nicht in IE <9 implementiert sind.
Tim Down

24

AKTUALISIERT: Kurzer Einzeiler , um die Duplikate zu erhalten:

[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) !== i) // [2, 4]

Um das Array ohne Duplikate zu erhalten, kehren Sie einfach die Bedingung um:

[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) === i) // [1, 2, 3, 4]

Ich habe filter()in meiner alten Antwort unten einfach nicht darüber nachgedacht;)


Wenn Sie nur überprüfen müssen, ob in dieser Frage keine Duplikate vorhanden sind , können Sie die folgende every()Methode verwenden:

[1, 2, 3].every((e, i, a) => a.indexOf(e) === i) // true

[1, 2, 1].every((e, i, a) => a.indexOf(e) === i) // false

Beachten Sie, dass every()dies für IE 8 und niedriger nicht funktioniert.


1
Wenn Sie nicht das tun, was das OP verlangt hat, geben Sie die Duplikate zurück.
RWC

Richtig, ich habe meine Antwort aktualisiert, um das zu beheben.
Laurent Payot

Königliche Lösung! Thnaks
Jeremy Piednoel

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

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

Dies scheint zu funktionieren, aber Sie sollten wahrscheinlich einen Text einfügen, der beschreibt, wie es funktioniert.
Der DIMM Reaper

1
Funktioniert nicht, wenn mehr als zwei doppelte Werte vorkommen.
Vasa

1
Das ist elegant und einfach. Ich liebe es. Für diejenigen, die herausfinden möchten, wie sie funktionieren, habe ich eine Übersicht erstellt, die zeigt, wie Duplikate angezeigt und Duplikate entfernt werden. Siehe hier: gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b
Josh

@ TheDIMMReaper für die Sekunde 'a'im Array, innerhalb des Filters Funktion der index == 1, währendself.indexOf('a') == 0
Sergiy Ostrovsky

19

Dies sollte Ihnen das bringen, 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.

13

mit underscore.js

function hasDuplicate(arr){
    return (arr.length != _.uniq(arr).length);
}

9

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],
    unique;

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

// create a new (dirty) Array with only the unique items
unique = unique.map((item,i) => unique.includes(item, i+1) ? item : '' )

// Cleanup - remove duplicate & empty items items 
unique = [...new Set(unique)].filter(n => n)

console.log(unique)


Suchen Sie eindeutige Werte aus 3 Arrays (oder mehr):

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

    return arr;
}

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

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

Nur eine Polyfüllung für das Array indexOf für alte Browser:

if (!Array.prototype.indexOf){
   Array.prototype.indexOf = function(elt /*, from*/){
     var len = this.length >>> 0;

     var from = Number(arguments[1]) || 0;
     from = (from < 0) ? Math.ceil(from) : Math.floor(from);
     if (from < 0)
        from += len;

     for (; from < len; from++){
        if (from in this && this[from] === elt)
           return from;
     }
     return -1;
  };
}

jQuery-Lösung mit "inArray":

if( $.inArray(this[i], arr) == -1 )

anstatt das hinzuzufügen Array.prototype.indexOf


+1, weil der Code mit Array.indexOf definitiv besser lesbar ist, aber leider langsamer als mit einer einfachen verschachtelten Schleife. Sogar in Browsern, die Array.indexOf wie FF implementieren. Bitte schauen Sie sich diese Tests an, die ich hier durchgeführt habe: jsperf.com/array-unique2 und teilen Sie mir Ihre Gedanken mit.
Marco Demaio

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

@vsync Ich musste initialisieren, var r = [];damit dein Code funktioniert. Und arbeitete wie Charme.
Shekhar K. Sharma

@ Shekhardesigner - Es tut mir leid für die Mischung, für die Array Prototype-Lösung benötigen Sie keine rVariable
vsync

2
Wenn Sie nicht das tun, was das OP verlangt hat, geben Sie die Duplikate zurück.
RWC

8

Hier ist meine einfache und einzeilige Lösung.

Zuerst werden nicht eindeutige Elemente durchsucht, und dann wird das gefundene Array mithilfe von Set eindeutig.

Wir haben also am Ende eine Reihe von Duplikaten.

var array = [1, 2, 2, 3, 3, 4, 5, 6, 2, 3, 7, 8, 5, 22, 1, 2, 511, 12, 50, 22];

console.log([...new Set(
  array.filter((value, index, self) => self.indexOf(value) !== index))]
);


7

Dies ist mein Vorschlag (ES6):

let a = [1, 2, 3, 4, 2, 2, 4, 1, 5, 6]
let b = [...new Set(a.sort().filter((o, i) => o !== undefined && a[i + 1] !== undefined && o === a[i + 1]))]

// b is now [1, 2, 4]

1
Dadurch wird gemeldet, dass ein einzelnes Vorkommen von undefinedein Duplikat ist.
Dem Pilafian

1
@ DemPilafian danke, aktualisiert
lukaszkups

6
var a = [324,3,32,5,52,2100,1,20,2,3,3,2,2,2,1,1,1].sort();
a.filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});

oder wenn es zur prototyp.chain von Array hinzugefügt wird

//copy and paste: without error handling
Array.prototype.unique = 
   function(){return this.sort().filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});}

Siehe hier: https://gist.github.com/1305056


1
Die Filterfunktion sollte true oder false zurückgeben, nicht das Element selbst. Das Filtern eines Arrays mit Nullen hätte diese nicht zurückgegeben.
Mflodin

Ich i&&gehe auch davon aus, dass dies dazu dient, das Überschreiten der Grenzen des Arrays zu vermeiden, aber es bedeutet auch, dass das erste Element im sortierten Array nicht enthalten ist. In Ihrem Beispiel enthält 1das resultierende Array kein . Dh return i&&v!==o[i-1]?v:0;solltereturn v!==o[i-1];
mflodin

6

Schneller und eleganter Weg mit es6 Objekt Destrukturierung und Reduzierung

Es wird in O (n) ausgeführt (1 Iteration über das Array) und wiederholt keine Werte, die mehr als zweimal vorkommen

const arr = ['hi', 'hi', 'hi', 'bye', 'bye', 'asd']
const {
  dup
} = arr.reduce(
  (acc, curr) => {
    acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1
    if (acc.items[curr] === 2) acc.dup.push(curr)
    return acc
  }, {
    items: {},
    dup: []
  },
)

console.log(dup)
// ['hi', 'bye']


5

Hier ist die einfachste Lösung, die ich mir vorstellen kann:

    const arr = [-1, 2, 2, 2, 0, 0, 0, 500, -1, 'a', 'a', 'a']

    const filtered = arr.filter((el, index) => arr.indexOf(el) !== index)
    // => filtered = [ 2, 2, 0, 0, -1, 'a', 'a' ]

    const duplicates = [...new Set(filtered)]

    console.log(duplicates)
    // => [ 2, 0, -1, 'a' ]

Das ist es.

Hinweis:

  1. Es funktioniert mit beliebigen Zahlen, einschließlich 0Zeichenfolgen und negativen Zahlen, z. B. -1- Verwandte Frage: Alle eindeutigen Werte in einem JavaScript-Array abrufen (Duplikate entfernen)

  2. Das ursprüngliche Array arrbleibt erhalten ( filtergibt das neue Array zurück, anstatt das Original zu ändern)

  3. Das filteredArray enthält alle Duplikate. Es kann auch mehr als einen Wert enthalten (z. B. unser gefiltertes Array hier [ 2, 2, 0, 0, -1, 'a', 'a' ]).

  4. Wenn Sie erhalten möchten nur Werte , die doppelt vorhanden sind (Sie müssen nicht mehrere Duplikate mit dem gleichen Wert haben wollen) Sie verwenden können [...new Set(filtered)](ES6 hat ein Objekt Set , die nur eindeutige Werte speichern kann)

Hoffe das hilft.


5

Kürzeste Vanille JS :

[1,1,2,2,2,3].filter((v,i,a) => a.indexOf(v) !== i) // [1, 2, 2]

4

Hier ist ein sehr leichter und einfacher Weg:

var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
  if (codes.indexOf(codes[i]) != i) {
    codes.splice(i,1);
  }
}

Beste Antwort. Und wenn Benutzer doppelte Elemente Array wollen, habe ich dafür @brandon Code var i = Codes .length aktualisiert; var duplicate = []; while (i--) {if (Codes .indexOf (Codes [i])! = i) {if (duplicate.indexOf (Codes [i]) === -1) {duplicate.push (arr [i]) ;; } Codes.splice (i, 1); }}
Himanshu Shekhar

4

Mit ES6 (oder mit Babel oder Typescipt) können Sie einfach:

var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);

https://es6console.com/j58euhbt/


Ich kam unabhängig zur gleichen Syntax und wollte sie gerade als Lösung hinzufügen, als ich diese fand. Es ist wahrscheinlich nicht das wirtschaftlichste, aber es ist einfach.
nize

4

Einfacher Code mit ES6-Syntax (sortiertes Array von Duplikaten zurückgeben):

let duplicates = a => {d=[]; a.sort((a,b) => a-b).reduce((a,b)=>{a==b&&!d.includes(a)&&d.push(a); return b}); return d};

Wie benutzt man:

duplicates([1,2,3,10,10,2,3,3,10]);

1
.filter () wäre viel einfacher
tocqueville

4

Einzeiler

var arr = [9,1,2,4,3,4,9]
console.log(arr.filter((ele,indx)=>indx!==arr.indexOf(ele))) //get the duplicates
console.log(arr.filter((ele,indx)=>indx===arr.indexOf(ele))) //remove the duplicates


Was macht indx!das erste Beispiel?
Saylestyler

1
@saylestyler Hehe, das heißt indx !== ...- strikte Ungleichung.
Daria

nur für Array von Objekten hinzufügenresult.filter((ele,indx) => indx !== result.map(e => e.name).indexOf(ele.name));
x-magix

4

Diese Antwort kann auch hilfreich sein. Sie nutzt den reduce Operator / die Methode js , um Duplikate aus dem Array zu entfernen .

const result = [1, 2, 2, 3, 3, 3, 3].reduce((x, y) => x.includes(y) ? x : [...x, y], []);

console.log(result);


3
Wir können jetzt nur tun new Set([1, 2, 2, 3, 3, 3, 3]), um Duplikate zu entfernen
Kimbaudi

3

Die folgende Funktion (eine Variation der bereits erwähnten Funktion eliminDuplicates) scheint den Trick zu tun und gibt test2,1,7,5 für die Eingabe ["test", "test2", "test2", 1, 1, 1, 2 zurück , 3, 4, 5, 6, 7, 7, 10, 22, 43, 1, 5, 8]

Beachten Sie, dass das Problem in JavaScript seltsamer ist als in den meisten anderen Sprachen, da ein JavaScript-Array fast alles enthalten kann. Beachten Sie, dass Lösungen, die Sortieren verwenden, möglicherweise eine geeignete Sortierfunktion bereitstellen müssen. Ich habe diese Route noch nicht ausprobiert.

Diese spezielle Implementierung funktioniert für (mindestens) Zeichenfolgen und Zahlen.

function findDuplicates(arr) {
    var i,
        len=arr.length,
        out=[],
        obj={};

    for (i=0;i<len;i++) {
        if (obj[arr[i]] != null) {
            if (!obj[arr[i]]) {
                out.push(arr[i]);
                obj[arr[i]] = 1;
            }
        } else {
            obj[arr[i]] = 0;            
        }
    }
    return out;
}

3

Nur ES5 (dh es wird eine filter () - Polyfüllung für IE8 und darunter benötigt):

var arrayToFilter = [ 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3 ];

arrayToFilter.
    sort().
    filter( function(me,i,arr){
       return (i===0) || ( me !== arr[i-1] );
    });

Ich mag diese einfache Lösung. Wenn Sie jedoch die Duplikate möchten, müssen Sie zuerst diese Duplikate suchen und dann die Duplikatliste eindeutig machen. [0, 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3] .sort (). Filter (Funktion (me, i, arr) {return (i! == 0 ) && (me == arr [i-1]);}). filter (function (me, i, arr) {return (i === 0) || (me! == arr [i-1]) ;});
Greg

3

var arr = [2, 1, 2, 2, 4, 4, 2, 5];

function returnDuplicates(arr) {
  return arr.reduce(function(dupes, val, i) {
    if (arr.indexOf(val) !== i && dupes.indexOf(val) === -1) {
      dupes.push(val);
    }
    return dupes;
  }, []);
}

alert(returnDuplicates(arr));

Diese Funktion vermeidet den Sortierschritt und verwendet die Methode redu (), um Duplikate in ein neues Array zu verschieben, sofern es noch nicht vorhanden ist.


3

Dies ist wahrscheinlich einer der schnellsten Wege, um die Duplikate dauerhaft zehnmal schneller aus einem Array zu entfernen als die meisten Funktionen hier. Und 78-mal schneller in Safari

function toUnique(a,b,c){//array,placeholder,placeholder
 b=a.length;
 while(c=--b)while(c--)a[b]!==a[c]||a.splice(c,1)
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];
toUnique(array);
console.log(array);
  1. Prüfung: http://jsperf.com/wgu
  2. Demo: http://jsfiddle.net/46S7g/
  3. Weitere Informationen : https://stackoverflow.com/a/25082874/2450730

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

BEARBEITEN Wie in den Kommentaren angegeben, gibt diese Funktion ein Array mit Eindeutigkeiten zurück. Die Frage fragt jedoch nach den Duplikaten. In diesem Fall können Sie durch eine einfache Änderung dieser Funktion die Duplikate in ein Array verschieben. Mit der vorherigen Funktion werden toUniquedie Duplikate der Duplikate entfernt.

function theDuplicates(a,b,c,d){//array,placeholder,placeholder
 b=a.length,d=[];
 while(c=--b)while(c--)a[b]!==a[c]||d.push(a.splice(c,1))
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];

toUnique(theDuplicates(array));

7
"Wenn Sie den obigen Code nicht lesen können, lesen Sie ein Javascript-Buch." Diese Antwort enthält viel zu viel Code Golf. Wenn Sie die Variablen wie a, b, c benennen, ist der Code schwer zu lesen. Der Verzicht auf geschweifte Zahnspangen macht es noch schlimmer.
River Williamson

Die meisten meiner Antworten basieren auf Leistung und Platzersparnis (andere Lösungen sind bereits veröffentlicht) ... wenn Sie es nicht mögen, stimmen Sie ab ... sonst lernen Sie Javascript, lesen Sie ein js-Buch ... oder verwenden Sie jquery ... sie Haben Sie viel mehr Antworten, wenn Sie nach einer einfachen Lösung suchen. Wenn Sie wirklich etwas lernen möchten, erkläre ich Ihnen gerne den Kennbuchstaben pro Buchstabe. Da ich in Ihrem Kommentar keine echte Frage sehen kann, suchen Sie wahrscheinlich nur nach einem Motiv, um meine Antwort abzulehnen. Weiter ... ich habe kein Problem damit. Stellen Sie eine echte Frage oder sagen Sie mir etwas, das mit meinem Code nicht funktioniert.
Cocco

9
An Ihrem Code ist technisch nichts auszusetzen. Das Benennen der Variablen a, b, c, d usw. und das Verketten von while-Schleifen erschwert jedoch das Lesen des Codes. Der Code lehrt also nichts.
River Williamson

3

Verwenden Sie "Includes", um zu testen, ob das Element bereits vorhanden ist.

var arr = [1, 1, 4, 5, 5], darr = [], duplicates = [];

for(var i = 0; i < arr.length; i++){
  if(darr.includes(arr[i]) && !duplicates.includes(arr[i]))
    duplicates.push(arr[i])
  else
    darr.push(arr[i]);
}

console.log(duplicates);
<h3>Array with duplicates</h3>
<p>[1, 1, 4, 5, 5]</p>
<h3>Array with distinct elements</h3>
<p>[1, 4, 5]</p>
<h3>duplicate values are</h3>
<p>[1, 5]</p>


Der Code gibt zwar unterschiedliche Elemente zurück, führt jedoch nicht zum angegebenen Ergebnis. Bitte geben Sie den vollständigen korrekten Code an.
RWC

3

ES6 bietet die Set-Datenstruktur, bei der es sich im Grunde um ein Array handelt, das keine Duplikate akzeptiert. Mit der Set-Datenstruktur gibt es eine sehr einfache Möglichkeit, Duplikate in einem Array zu finden (mit nur einer Schleife).

Hier ist mein Code

function findDuplicate(arr) {
var set = new Set();
var duplicates = new Set();
  for (let i = 0; i< arr.length; i++) {
     var size = set.size;
     set.add(arr[i]);
     if (set.size === size) {
         duplicates.add(arr[i]);
     }
  }
 return duplicates;
}

3

Ich habe gerade einen einfachen Weg gefunden, dies mit einem Array-Filter zu erreichen

    var list = [9, 9, 111, 2, 3, 4, 4, 5, 7];
    
    // Filter 1: to find all duplicates elements
    var duplicates = list.filter(function(value,index,self) {
       return self.indexOf(value) !== self.lastIndexOf(value) && self.indexOf(value) === index;
    });
    
    console.log(duplicates);


3

Das Befolgen der Logik wird einfacher und schneller

// @Param:data:Array that is the source 
// @Return : Array that have the duplicate entries
findDuplicates(data: Array<any>): Array<any> {
        return Array.from(new Set(data)).filter((value) => data.indexOf(value) !== data.lastIndexOf(value));
      }

Vorteile:

  1. Einzeilig :-P
  2. Alle eingebauten Datenstrukturen tragen zur Verbesserung der Effizienz bei
  3. Schneller

Beschreibung der Logik:

  1. Konvertieren in Set, um alle Duplikate zu entfernen
  2. Durchlaufen der eingestellten Werte
  3. Bei jeder eingestellten Wertprüfung im Quellarray auf die Bedingung "Werte erster Index ist nicht gleich letzter Index" ==> Dann als Duplikat abgeleitet, sonst ist es 'eindeutig'.

Hinweis: Die Methoden map () und filter () sind effizient und schneller.


1
Getestet ... sehr schnell. und es macht Sinn .. wünschte, ich hätte darüber nachgedacht
Michael Rhema
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.