Uzyskaj wszystkie nieunikalne wartości (tj .: duplikat / więcej niż jedno wystąpienie) w tablicy


418

Muszę sprawdzić tablicę JavaScript, aby zobaczyć, czy istnieją jakieś zduplikowane wartości. Jak najłatwiej to zrobić? Muszę tylko dowiedzieć się, jakie są zduplikowane wartości - tak naprawdę nie potrzebuję ich indeksów ani ile razy są one duplikowane.

Wiem, że mogę przeglądać tablicę i sprawdzać wszystkie pozostałe wartości, ale wydaje się, że powinien istnieć łatwiejszy sposób.

Podobne pytanie:


22
Wydaje się, że minęły lata zamieszania na temat tego, o co pyta to pytanie. Musiałem wiedzieć, które elementy w tablicy zostały zduplikowane: „Muszę tylko znaleźć, jakie są zduplikowane wartości”. Prawidłowa odpowiedź NIE powinna usuwać duplikatów z tablicy. To jest odwrotność tego, co chciałem: lista duplikatów, a nie lista unikalnych elementów.
Scott Saunders

Odpowiedzi:


301

Możesz posortować tablicę, a następnie uruchomić ją, a następnie sprawdzić, czy następny (lub poprzedni) indeks jest taki sam jak bieżący. Zakładając, że Twój algorytm sortowania jest dobry, powinno być mniejsze niż O (n 2 ):

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)}`);

W przypadku, jeśli chcesz powrócić jako funkcja dla duplikatów. Dotyczy to podobnych przypadków.

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


10
„Zakładając, że twój algorytm sortowania jest dobry, powinno być mniejsze niż O ^ 2”. W szczególności może to być O (n * log (n)).
ESRogs

83
Ten skrypt nie działa tak dobrze z więcej niż 2 duplikatami (np.arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
Mottie

7
@swilliams Nie sądzę, że te wytyczne mówią coś o nie używaniu i++. Zamiast tego mówią, żeby nie pisać j = i + +j. Dwie różne rzeczy IMHO. Myślę, że i += 1jest to bardziej mylące niż proste i piękne i++:)
Danilo Bargen

34
-1 Ta odpowiedź jest błędna na wielu poziomach. Przede wszystkim var sorted_arr = arr.sort()jest bezużyteczny: arr.sort()mutuje oryginalną tablicę (co samo w sobie jest problemem). To także odrzuca element. (Uruchom powyższy kod. Co się stanie z 9?) Cc @dystroy Czystszym rozwiązaniem byłobyresults = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
NullUserException

24
Wszyscy: pytanie wymaga wyświetlenia zduplikowanych wartości, a nie ich usunięcia. Proszę nie edytować / łamać kodu, aby spróbować zrobić coś, czego nie próbuje zrobić. Alert powinien zawierać wartości, które są zduplikowane.
Scott Saunders

205

Jeśli chcesz usunąć duplikaty, wypróbuj to świetne rozwiązanie:

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;
}

Źródło: http://dreaminginjavascript.wordpress.com/2008/08/22/ Eliminating-duplicates/


18
To dobry kod, ale niestety nie robi tego, o co proszę.
Scott Saunders

67
Powyższy kod (który jest mój - to mój blog) przybliża cię do siebie. Mała poprawka i już tam jesteś. Przede wszystkim możesz sprawdzić, czy długość arr. I długość out są takie same. Jeśli są takie same, nie ma zduplikowanych elementów. Ale chcesz trochę więcej. Jeśli chcesz „złapać” duplikaty, gdy się zdarzają, sprawdź, czy długość tablicy wzrasta po linii obj [arr [i]] = 0. Zręczne, co? :-) Dzięki za miłe słowa, Raphael Montanaro.
Nosredna

6
@MarcoDemaio: Uh, nie, dlaczego kod nie działa ze spacjami? Możesz wpisać co chcesz w nazwie właściwości - po prostu nie możesz użyć składni kropki, aby uzyskać dostęp do tych ze spacjami (ani rekwizytów z różnymi innymi znakami, które mogłyby przerwać parsowanie).
Gijs,

4
@Gijs: +1 masz rację. Nie wiedziałem tego Ale nadal nie działa, gdy jest to tablica obiektów.
Marco Demaio

3
Ten algorytm ma również efekt uboczny polegający na zwróceniu posortowanej tablicy, co może nie być tym, czego chcesz.
asymetryczny

165

Oto moja odpowiedź ze zduplikowanego wątku (!):

Pisząc ten wpis 2014 - wszystkie przykłady dotyczyły pętli lub jQuery. JavaScript ma do tego idealne narzędzia: sortuj, mapuj i zmniejszaj.

Znajdź zduplikowane elementy

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' ]

Bardziej funkcjonalna składnia:

@ Dmytro-Laptin wskazał, że należy usunąć część kodu. To jest bardziej kompaktowa wersja tego samego kodu. Korzystanie z niektórych sztuczek ES6 i funkcji wyższego rzędu:

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
Tego rodzaju rozwiązania szukałem. Gdybym chciał mieć tuzin pętli for, łatwo byłoby to napisać. Kluczowym słowem w PO było „skuteczne”.
Josh

@ChristianLandgren, gdzie deklarowana jest zmienna „dict”? może zamiast tego należy użyć „count”?
Dmytro Laptin

4
Zachowaj swoją mylącą opinię dla siebie (-1 za bycie aroganckim). Osobiście mam dość ludzi mylących „krótkich” i „wydajnych” oraz publikujących jedno-linijki bez kwestionowania występów. Krótkie programy i współczesne JS NIE są z natury lepsze. Typowe niewłaściwe użycie słowa „wydajny” tutaj . Typowe naiwne przekonanie tutaj (przeczytaj poniższe komentarze). Demo tutaj .
liść

1
@leaf - zachowaj sugestie dotyczące własnych odpowiedzi. Rozwiązanie, które edytowałeś, nie jest czytelne, może być wydajne (prawdopodobnie nie), ale mimo to - czytelność często jest ważniejsza niż wydajność. Ale co najważniejsze - nie usuwaj cudzego kodu, aby zastąpić go swoim bez powodu.
Christian Landgren,

1
Różne odpowiedzi, tak, różne opinie, nie sądzę.
liść

64

Znajdź zduplikowane wartości w tablicy

To powinien być jeden z najkrótszych sposobów, aby faktycznie znaleźć zduplikowane wartości w tablicy. Jak wyraźnie zażądał PO, nie usuwa to duplikatów, ale je odnajduje .

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])

Nie wymaga to sortowania ani żadnych struktur zewnętrznych. Nie potrzebuje też ręcznych pętli. Działa z każdą wartością indexOf () (lub ściślej: operator ścisłego porównania ).

Ze względu na redukcję () i indexOf () potrzebuje co najmniej IE 9.


7
ES6 strzałka / wersja prosta / czysta:const dupes = items.reduce((acc, v, i, arr) => arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc, [])
ZephDavies,

30

Możesz dodać tę funkcję lub dostosować ją i dodać do prototypu JavaScript Array:

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);

Jest to najlepsze rozwiązanie, ale należy zachować ostrożność przed dodaniem go do prototypu macierzy, ponieważ spowoduje to popsucie IE, jeśli będą przechodzić przez wartości.
Sampsa Suoninen

@RoyTinker perl też je obsługuje, ale nie miałem pojęcia, że ​​javascript to zrobił
Luke H

1
Nie robi tego, o co poprosił PO, zwraca duplikaty.
RWC

27

ZAKTUALIZOWANO: Poniżej zastosowano zoptymalizowaną połączoną strategię. Optymalizuje pierwotne wyszukiwania, aby skorzystać z czasu wyszukiwania skrótu O (1) (uruchamianie uniquena tablicy prymitywów to O (n)). Wyszukiwanie obiektów jest optymalizowane poprzez oznaczanie obiektów unikalnym identyfikatorem podczas iteracji, więc identyfikacja zduplikowanych obiektów to także O (1) na element i O (n) dla całej listy. Jedynym wyjątkiem są elementy, które są zamrożone, ale są one rzadkie, a awaryjne zapewnia się za pomocą tablicy i indexOf.

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;
}();

Jeśli masz dostępne kolekcje ES6, istnieje o wiele prostsza i znacznie szybsza wersja. (podkładka dla IE9 + i innych przeglądarek tutaj: 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;
    }
  });
}

naprawdę? po co odpowiadać na pytanie, które zostało rozwiązane ponad 2 lata temu?
Rene Pot

3
Odpowiadałem na inne pytanie i najwyraźniej przypadkowo kliknąłem kogoś, kto łączy się z tym, nazywając go duplikatem, i ostatecznie sklonowałem moją odpowiedź i zdziwiłem się. Dużo edytuję swoje rzeczy.


16
Myślę, że to miłe z różnymi rozwiązaniami. Nie ma znaczenia, że ​​temat jest stary i rozwiązany, ponieważ wciąż można wymyślić różne sposoby na zrobienie tego. To typowy problem w informatyce.
Emil Vikström

Warto wspomnieć, że opiera się to na metodach tablicy ES5, które nie są zaimplementowane w IE <9.
Tim Down

24

ZAKTUALIZOWANY: Krótki jednowarstwowy, aby uzyskać duplikaty:

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

Aby uzyskać tablicę bez duplikatów, po prostu odwróć warunek:

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

Po prostu nie myślałem o tym filter()w mojej starej odpowiedzi poniżej;)


Gdy wszystko, czego potrzebujesz, to sprawdzić, czy nie ma duplikatów zgodnie z pytaniem w tym pytaniu , możesz użyć every()metody:

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

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

Pamiętaj, że every()nie działa dla IE 8 i niższych.


1
Nie robi tego, o co poprosił PO, zwraca duplikaty.
RWC

To prawda, zaktualizowałem swoją odpowiedź, aby to naprawić.
Laurent Payot

Królewskie rozwiązanie! thnaks
Jeremy Piednoel

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

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

Wydaje się, że to działa, ale prawdopodobnie powinieneś dołączyć tekst opisujący, jak to działa.
DIMM Reaper

1
Nie będzie działać, jeśli wystąpią więcej 2 wystąpienia zduplikowanej wartości.
vasa

1
To jest eleganckie i proste. Kocham to. Dla tych, którzy chcą dowiedzieć się, jak działają, stworzyłem istotę pokazującą, jak pokazywać duplikaty i eliminować duplikaty. Zobacz tutaj: gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b
Josh

@TheDIMMReaper dla drugiego 'a'w tablicy, funkcja filtra wewnątrz index == 1, natomiastself.indexOf('a') == 0
Sergiy Ostrovsky

19

To powinno dać ci to, czego chcesz, tylko duplikaty.

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

using 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)


Znajdź unikalne wartości z 3 tablic (lub więcej):

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]

Tylko polifill dla indeksu tablicowego dla starych przeglądarek:

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;
  };
}

Rozwiązanie jQuery przy użyciu „inArray”:

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

zamiast dodawać Array.prototype.indexOf


+1, ponieważ kod jest zdecydowanie bardziej czytelny przy użyciu Array.indexOf, ale niestety wydaje się wolniejszy niż przy użyciu prostej zagnieżdżonej pętli. Nawet w przeglądarkach, które implementują Array.indexOf naiwnie jak FF. Proszę, spójrz na te testy, które zrobiłem tutaj: jsperf.com/array-unique2 i daj mi znać, co myślisz .
Marco Demaio,

@shekhardesigner - zaktualizowana odpowiedź. „r” to tablica, w której
szukasz

@vsync Musiałem zainicjować, var r = [];aby twój kod działał. I działał jak urok.
Shekhar K. Sharma

@shekhardesigner - Przepraszam za mix, dla rozwiązania Array Prototype nie potrzebujesz rzmiennej
vsync

2
Nie robi tego, o co poprosił PO, zwraca duplikaty.
RWC

8

Oto moje proste i jedno liniowe rozwiązanie.

Najpierw przeszukuje nie unikalne elementy, a następnie czyni tablicę unikalną za pomocą Set.

Mamy więc na końcu szereg duplikatów.

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

Oto moja propozycja (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
Spowoduje to zgłoszenie, że pojedyncze wystąpienie undefinedjest duplikatem.
Dem Pilafian,

1
@DemPilafian dziękuję, zaktualizowano
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;});

lub po dodaniu do prototyp.chain Array

//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;});}

Zobacz tutaj: https://gist.github.com/1305056


1
Funkcja filtrowania powinna zwracać wartość prawda lub fałsz, a nie sam element. Filtrowanie tablicy zawierającej 0 nie zwróciłoby ich.
mflodin

Zakładam również, że i&&ma to na celu uniknięcie przekroczenia granicy tablicy, ale oznacza to również, że pierwszy element w posortowanej tablicy nie zostanie uwzględniony. W twoim przykładzie nie ma 1wynikowej tablicy. To return i&&v!==o[i-1]?v:0;return v!==o[i-1];
znaczy

6

Szybki i elegancki sposób z wykorzystaniem destrukcji i redukcji obiektów es6

Działa w O (n) (1 iteracja po tablicy) i nie powtarza wartości, które pojawiają się więcej niż 2 razy

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

Oto najprostsze rozwiązanie, jakie mogłem wymyślić:

    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' ]

Otóż ​​to.

Uwaga:

  1. Działa z dowolnymi liczbami, w tym 0ciągami i liczbami ujemnymi, np. -1- Powiązane pytanie: Uzyskaj wszystkie unikalne wartości w tablicy JavaScript (usuń duplikaty)

  2. Oryginalna tablica arrzostaje zachowana ( filterzwraca nową tablicę zamiast modyfikować oryginał)

  3. filteredTablica zawiera wszystkie duplikaty; to może również zawierać więcej niż 1 samą wartość (np naszą filtrowanego układ jest tu [ 2, 2, 0, 0, -1, 'a', 'a' ])

  4. Jeśli chcesz uzyskać tylko wartości, które są zduplikowane (nie chcesz mieć wielu duplikatów o tej samej wartości), możesz użyć [...new Set(filtered)](ES6 ma zestaw obiektów, który może przechowywać tylko unikalne wartości)

Mam nadzieję że to pomoże.


5

Najkrótsza waniliowa JS :

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

4

Oto bardzo lekki i łatwy sposób:

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

Najlepsza odpowiedź. A jeśli użytkownik chce duplikować tablicę elementów, w tym celu zaktualizowałem @brandon kod var i = kody .length; var duplicate = []; while (i--) {if (kody .indexOf (kody [i])! = i) {if (duplicate.indexOf (kody [i]) === -1) {duplicate.push (arr [i]) ; } kody.splice (i, 1); }}
Himanshu Shekhar

4

Za pomocą ES6 (lub używając Babel lub Typescipt) możesz po prostu:

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

https://es6console.com/j58euhbt/


Doszedłem do tej samej składni niezależnie i właśnie miałem ją dodać jako rozwiązanie, gdy ją znalazłem. Prawdopodobnie nie jest to najbardziej ekonomiczny, ale jest prosty.
nize

4

Prosty kod ze składnią ES6 (zwraca posortowaną tablicę duplikatów):

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};

Jak używać:

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

1
.filter () byłby znacznie prostszy
tocqueville

4

jedna wkładka

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


co robi indx!dla pierwszego przykładu?
saylestyler

1
@saylestyler Hehe, oznacza to indx !== ...- ścisłą nierówność.
Daria

dodawanie tylko dla tablicy obiektówresult.filter((ele,indx) => indx !== result.map(e => e.name).indexOf(ele.name));
x-magix

4

Ta odpowiedź może być również pomocna, wykorzystuje reduce operatora / metodę js do usuwania duplikatów z tablicy.

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

console.log(result);


3
możemy teraz zrobić, new Set([1, 2, 2, 3, 3, 3, 3])aby usunąć duplikaty
kimbaudi,

3

Następująca funkcja (wspomniana już odmiana funkcji eliminacji duplikatów) wydaje się załatwić sprawę, zwracając test2,1,7,5 dla danych wejściowych [„test”, „test2”, „test2”, 1, 1, 1, 2 , 3, 4, 5, 6, 7, 7, 10, 22, 43, 1, 5, 8]

Zauważ, że problem jest dziwniejszy w JavaScript niż w większości innych języków, ponieważ tablica JavaScript może pomieścić prawie wszystko. Zwróć uwagę, że rozwiązania wykorzystujące sortowanie mogą wymagać zapewnienia odpowiedniej funkcji sortowania - jeszcze nie próbowałem tej trasy.

Ta konkretna implementacja działa dla (przynajmniej) ciągów i liczb.

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

Tylko ES5 (tzn. Wymaga wypełnienia filtra () dla IE8 i niższych):

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] );
    });

Podoba mi się to proste rozwiązanie. Jeśli chcesz duplikaty, najpierw musisz je znaleźć, a następnie uczynić listę duplikatów unikalną. [0, 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3] .sort (). Filter (funkcja (ja, 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));

Ta funkcja unika kroku sortowania i używa metody redukowania () do wypychania duplikatów do nowej tablicy, jeśli jeszcze w niej nie istnieje.


3

Jest to prawdopodobnie jeden z najszybszych sposobów na trwałe usunięcie duplikatów z tablicy 10 razy szybciej niż większość funkcji tutaj. I 78 razy szybciej w 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. Test: http://jsperf.com/wgu
  2. Demo: http://jsfiddle.net/46S7g/
  3. Więcej: https://stackoverflow.com/a/25082874/2450730

jeśli nie możesz odczytać powyższego kodu, zapytaj, przeczytaj książkę javascript lub oto wyjaśnienia dotyczące krótszego kodu. https://stackoverflow.com/a/21353032/2450730

EDYCJA Jak stwierdzono w komentarzach, funkcja zwraca tablicę z unikatami, jednak pytanie wymaga znalezienia duplikatów. w takim przypadku prosta modyfikacja tej funkcji pozwala na wypchnięcie duplikatów do tablicy, a następnie użycie poprzedniej funkcji toUniqueusuwa duplikaty duplikatów.

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
„jeśli nie możesz odczytać powyższego kodu zapytaj, przeczytaj książkę javascript” W tej odpowiedzi jest zbyt wiele kodu golfa. Nazewnictwo zmiennych takich jak a, b, c sprawia, że ​​kod jest trudny do odczytania. Rezygnacja z nawiasów klamrowych czyni go jeszcze gorszym.
Rzeka Williamson,

Większość moich odpowiedzi opiera się na wydajności i oszczędności miejsca (inne rozwiązania są już opublikowane) ... jeśli nie podoba ci się to głosuj ... inaczej naucz się javascript, przeczytaj książkę js ... lub użyj jquery ... one masz dużo więcej odpowiedzi, jeśli szukasz prostego rozwiązania. Jeśli naprawdę chcesz się czegoś nauczyć, chętnie wyjaśnię literę kodu na literę. Ponieważ nie widzę prawdziwego pytania w twoim komentarzu, myślę, że właśnie szukasz motywu, aby głosować za moją odpowiedzią ... kontynuuj ... nie mam z tym problemu. Zadaj prawdziwe pytanie lub powiedz mi coś, co nie działa z moim kodem.
cocco,

9
Z twoim kodem nie ma nic technicznego. To powiedziawszy, nazywanie zmiennych a, b, c, d itd. I łączenie w pętle while powoduje, że kod jest trudny do odczytania. Tak więc kod niczego nie uczy.
Rzeka Williamson,

3

Użycie „obejmuje”, aby sprawdzić, czy element już istnieje.

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>


Kod zwraca odrębne elementy, ale nie prowadzi do podanego wyniku. Podaj kompletny poprawny kod.
RWC

3

ES6 oferuje strukturę danych Set, która jest w zasadzie tablicą, która nie przyjmuje duplikatów. Dzięki strukturze danych Set istnieje bardzo łatwy sposób na znalezienie duplikatów w tablicy (przy użyciu tylko jednej pętli).

Oto mój kod

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

Właśnie wymyśliłem prosty sposób na osiągnięcie tego za pomocą filtra Array

    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

Przestrzeganie logiki będzie łatwiejsze i szybsze

// @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));
      }

Zalety :

  1. Pojedyncza linia :-P
  2. Wszystkie wbudowane struktury danych pomagają poprawić wydajność
  3. Szybciej

Opis logiki:

  1. Konwertowanie na ustawienie usuwania wszystkich duplikatów
  2. Iteracja po ustawionych wartościach
  3. Przy każdej ustawionej wartości sprawdź w tablicy źródłowej warunek „wartości pierwszy indeks nie jest równy ostatniemu indeksowi” ==> Następnie wywnioskowano jako duplikat, w przeciwnym razie jest „unikalny”

Uwaga: metody map () i filter () są wydajne i szybsze.


1
Testowałem to ... bardzo szybko. i to ma sens .. chciałbym o tym pomyśleć
Michael Rhema,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.