Bir dizideki benzersiz olmayan tüm değerleri (örneğin: yinelenen / birden fazla tekrar) elde etme


418

Yinelenen değerler olup olmadığını görmek için bir JavaScript dizisini kontrol etmek gerekiyor. Bunu yapmanın en kolay yolu nedir? Ben sadece çoğaltılan değerlerin ne olduğunu bulmak gerekir - Aslında onların dizinleri veya kaç kez çoğaltılamazlar.

Dizi üzerinden döngü ve bir maç için diğer tüm değerleri kontrol biliyorum, ama daha kolay bir yol olmalı gibi görünüyor.

Benzer soru:


22
Bu sorunun ne istediğiyle ilgili yıllarca kafa karışıklığı var gibi görünüyor. Ben dizideki öğeleri çoğaltılmış bilmek gerekiyordu: "Ben sadece çoğaltılan değerlerin ne olduğunu bulmak gerekir". Doğru cevap diziden yinelenenleri SİLMEMELİDİR. İstediğimin tersi de bu: benzersiz öğelerin bir listesi değil, kopyaların bir listesi.
Scott Saunders

Yanıtlar:


301

Diziyi sıralayabilir ve ardından onu çalıştırabilir ve sonraki (veya önceki) dizinin geçerli ile aynı olup olmadığını görebilirsiniz. Sıralama algoritmanızın iyi olduğunu varsayarsak, bu O (n 2 ) değerinden daha az olmalıdır :

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

Bu durumda, kopyalar için bir işlev olarak dönecek olursanız. Bu benzer bir durum içindir.

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


10
"Sıralama algoritmanızın iyi olduğunu varsayarsak, bu O ^ 2'den küçük olmalıdır". Özellikle, O (n * log (n)) olabilir.
ESRogs

83
Bu script 2'den fazla kopya ile çok iyi çalışmıyor (örn.arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
Mottie

7
@swilliams Bu yönergelerin kullanmama hakkında bir şey söylediğini sanmıyorum i++. Bunun yerine yazmamalarını söylüyorlar j = i + +j. İki farklı şey IMHO. Bence i += 1basit ve i++
güzelden

34
-1 Bu cevap birçok düzeyde yanlıştır. Her şeyden önce var sorted_arr = arr.sort()işe yaramaz: arr.sort()orijinal diziyi değiştirir (bu kendi başına bir sorundur). Bu aynı zamanda bir unsuru atar. (Yukarıdaki kodu çalıştırın. 9'a ne olur?) Cc @dystroy Daha temiz bir çözüm olurduresults = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
NullUserException

24
Herkes: soru, yinelenen değerleri kaldırmayı değil göstermeyi ister. Lütfen yapmaya çalışmadığı bir şeyi yapmak için kodu düzenlemeyin / kırmayın. Uyarı, çoğaltılan değerleri göstermelidir.
Scott Saunders

205

Kopyaları kaldırmak istiyorsanız, bu harika çözümü deneyin:

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

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


18
Bu iyi bir kod ama maalesef istediğim şeyi yapmıyor.
Scott Saunders

67
Yukarıdaki kod (bu benim - bu benim blogum) sizi oldukça yaklaştırıyor. Küçük bir değişiklik ve oradasınız. Her şeyden önce, arr.length ve out.length'in aynı olup olmadığını görebilirsiniz. Aynılarsa, yinelenen öğeler yoktur. Ama biraz daha fazlasını istiyorsun. Dupes'leri gerçekleştikçe "yakalamak" istiyorsanız, obj [arr [i]] = 0 satırından sonra dizinin uzunluğunun artıp artmadığını kontrol edin. Şık, ha? :-) Güzel sözler için teşekkürler, Raphael Montanaro.
Nosredna

6
@MarcoDemaio: Ah, hayır, kod neden boşluklarla çalışmaz? Bir özellik adına istediğiniz her şeyi koyabilirsiniz - nokta sözdizimini boşluklu olanlara erişmek için kullanamazsınız (ayrıştırmayı kıracak çeşitli diğer karakterlerle sahne alır).
Gijs

4
@Gijs: +1 haklısın. Bilmiyordum. Ancak bir nesne dizisi olduğunda hala çalışmaz.
Marco Demaio

3
Bu algoritma, sıralı bir dizi döndürmenin yan etkisine de sahiptir; bu, istediğiniz gibi olmayabilir.
asimetrik

165

Bu benim yinelenen iş parçacığından (!) Cevabım:

Bu girişi 2014 yazarken - tüm örnekler döngüler veya jQuery idi. Javascript bunun için mükemmel araçlara sahiptir: sıralama, haritalama ve azaltma.

Yinelenen öğeleri bulma

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

Daha işlevsel sözdizimi:

@ Dmytro-Laptin bazı kod kodlarının kaldırılacağına dikkat çekti. Bu, aynı kodun daha kompakt bir sürümüdür. Bazı ES6 numaralarını ve daha yüksek dereceli işlevleri kullanma:

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
Aradığım bu tür bir çözüm. Eğer bir düzine döngüye sahip olmak istersem, bunu yazmak oldukça kolay olurdu. OP anahtar kelimesi "verimli" idi.
Josh

@ChristianLandgren, 'dict' değişkeni nerede bildirilir? belki 'sayım' yerine kullanılmalıdır?
Dmytro Laptin

4
Lütfen yanıltıcı görüşünüzü kendiniz saklayın (küstah olmak için -1). Kişisel olarak "kısa" ve "verimli" kafa karıştırıcılardan ve performansları sorgulamadan tek gömlek göndermekten bıktım. Kısa programlar ve modern JS doğası gereği daha iyi DEĞİLDİR. Burada "verimli" kelimesinin tipik yanlış kullanımı . Tipik naif inanç burada (şu açıklamaları okuyun). Burada demo .
yaprak

1
@leaf - lütfen önerilerinizi kendi yanıtlarınıza saklayın. Düzenlediğiniz çözüm okunabilir değil, performans gösterebilir (muhtemelen olmayabilir), ancak öyle olsa bile - okunabilirlik genellikle bence performanstan daha önemlidir. Ama en önemlisi - başka birinin kodunu kendi adınızla değiştirmeden nedenini kaldırmayın.
Christian Landgren

1
Farklı cevaplar, evet, farklı görüşler, sanmıyorum.
yaprak

64

Bir dizideki yinelenen değerleri bulma

Bu, bir dizideki yinelenen değerleri bulmanın en kısa yollarından biri olmalıdır. OP tarafından özellikle istendiği gibi, bu kopyaları kaldırmaz ancak bulur .

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

Bunun sıralamaya veya herhangi bir üçüncü taraf çerçevesine ihtiyacı yoktur. Ayrıca manuel döngülere de gerek yoktur. Her değer indexOf () (veya daha açık olmak gerekirse: sıkı karşılaştırma operatörü ile çalışır) ) desteklediği .

Yüzünden azaltmak () ve indexOf () o en az IE 9 gerekiyor.


7
ES6 ok / basit / saf sürüm:const dupes = items.reduce((acc, v, i, arr) => arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc, [])
ZephDavies

30

Bu işlevi ekleyebilir veya düzenleyebilir ve Javascript'in Array prototipine ekleyebilirsiniz:

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

Bu en iyi çözümdür, ancak dizi prototipine eklemeye dikkat edin, çünkü bu değerler arasında döngü yaparsa IE'yi kirletecektir.
Sampsa Suoninen

@RoyTinker perl de onları destekliyor, ancak javascript yaptım hiçbir fikrim yoktu
Luke H

1
OP'nin istediği şeyi yapmaz, kopyaları iade edin.
RWC

27

GÜNCELLENDİ: Aşağıda optimize edilmiş birleşik strateji kullanılmaktadır. İlkel aramaları, hash O (1) arama süresinden faydalanmak için optimize eder ( uniquebir ilkel dizi üzerinde çalışan O (n) 'dir). Nesne aramaları, yineleme sırasında benzersiz bir kimliğe sahip nesneleri etiketleyerek optimize edilir, böylece yinelenen nesneleri tanımlamak öğe başına O (1) ve tüm liste için O (n) olur. Tek istisna dondurulmuş öğelerdir, ancak bunlar nadirdir ve bir dizi ve indexOf kullanılarak bir geri dönüş sağlanır.

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

ES6 Koleksiyonlarınız varsa, çok daha basit ve çok daha hızlı bir sürüm var. (IE9 + ve diğer tarayıcılar için şim: 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;
    }
  });
}

Gerçekten mi? Neden 2 yıl önce çözülmüş bir soruyu cevaplıyoruz?
Rene Pot

3
Başka bir soruyu cevaplıyordum ve görünüşe göre yanlışlıkla bu soruna bağlanan birisine tıkladım, bir kopyasını çağırdım ve cevabımı klonladım ve cehennemi kendim karıştırdım. Eşyalarımı çok düzenliyorum.


16
Farklı çözümlerle güzel olduğunu düşünüyorum. Konunun eski ve çözülmüş olması önemli değil, çünkü bunu yapmanın farklı yollarını bulmak hala mümkün. Bilgisayar biliminde tipik bir problemdir.
Emil Vikström

Bunun IE <9'da uygulanmayan ES5 Dizi yöntemlerine dayandığını belirtmek isteyebilirsiniz
Tim Down

24

GÜNCELLENDİ: Kopyaları almak için kısa bir astar:

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

Diziyi yinelenmeden almak için koşulu tersine çevirmeniz yeterlidir:

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

Sadece filter()aşağıdaki eski cevabımda düşünmedim ;)


Tek ihtiyacınız olan, bu soruda sorulduğu gibi kopya olmadığını kontrol etmek olduğunda , every()yöntemi kullanabilirsiniz :

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

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

Not every()Aşağıdaki IE 8 ve için çalışmaz.


1
OP'nin istediği şeyi yapmaz, kopyaları iade edin.
RWC

Doğru, bunu düzeltmek için cevabımı güncelledim.
Laurent Payot

Kraliyet çözümü! thnaks
Jeremy Piednoel

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

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

Bu işe yarıyor gibi görünüyor, ancak muhtemelen nasıl çalıştığını açıklayan bir metin eklemelisiniz.
DIMM Reaper

1
Yinelenen bir değerin 2'den fazla tekrarlanması durumunda çalışmaz.
vasa

1
Bu zarif ve basit. Onu seviyorum. Nasıl çalıştıklarını anlamak isteyenler için, kopyaların nasıl gösterileceğini ve kopyaların nasıl ortadan kaldırılacağını gösteren bir özüm oluşturdum. Buraya bakın: gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b
Josh

@TheDIMMReaper 'a'dizide ikinci , filtre fonksiyonu içinde index == 1iken,self.indexOf('a') == 0
Sergiy Ostrovsky

19

Bu istediğinizi elde etmeli, Sadece kopyalar.

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

underscore.js kullanma

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)


3 diziden (veya daha fazlasından) benzersiz değerleri bulun:

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]

Eski tarayıcılar için dizi index için bir çoklu dolgu:

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

"inArray" kullanarak jQuery çözümü:

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

eklemek yerine Array.prototype.indexOf


+1, çünkü kodu Array.indexOf kullanarak kesinlikle daha okunabilir, ancak maalesef basit bir iç içe döngü kullanmaktan daha yavaş görünüyor. Array.index'i FF gibi tek başına uygulayan tarayıcılarda bile. Plz, burada yaptığım şu testlere bir göz atın: jsperf.com/array-unique2 ve düşüncelerinizi bana bildirin.
Marco Demaio

@shekhardesigner - cevap güncellendi. "r", aradığınız dizidir
vsync

@vsync Kodunuzu çalıştırmak için başlatmam var r = [];gerekiyordu. Ve çekicilik gibi çalıştı.
Shekhar K. Sharma

@shekhardesigner - Karışım için üzgünüm, Array Prototype çözümü için bir rdeğişkene ihtiyacınız yok
vsync

2
OP'nin istediği şeyi yapmaz, kopyaları iade edin.
RWC

8

İşte benim basit ve tek satırlık bir çözüm.

Öncelikle benzersiz öğeleri aramaz, ardından bulunan diziyi Set kullanımı ile benzersiz kılar.

Sonunda bir dizi kopya var.

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

Bu benim teklifim (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
Bu, tek bir oluşumunun undefinedbir kopya olduğunu bildirecektir .
Dem Pilafian

1
@DemPilafian teşekkür ederim, güncellendi
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;});

veya Arty prototipine eklendiğinde.

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

Buraya bakın: https://gist.github.com/1305056


1
Filtre işlevi, öğenin kendisini değil, doğru veya yanlış döndürmelidir. 0 içeren bir diziye filtre uygulamak onları döndürmezdi.
mflodin

Ayrıca, i&&dizinin sınırları dışına çıkmaktan kaçınmak için olduğunu varsayıyorum , ama aynı zamanda sıralanan dizideki ilk elemanın dahil edilmeyeceği anlamına gelir. Örneğinizde 1, sonuçta ortaya çıkan dizide yok. Yani return i&&v!==o[i-1]?v:0;olmalıreturn v!==o[i-1];
mflodin

6

ES6 nesne yok etme ve azaltmanın hızlı ve zarif yolu

O (n) (dizi üzerinde 1 yineleme) ile çalışır ve 2 kereden fazla görünen değerleri tekrarlamaz

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

İşte aklıma gelen en basit çözüm:

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

Bu kadar.

Not:

  1. 0Dizeler ve negatif sayılar dahil olmak üzere herhangi bir sayı ile çalışır Örneğin -1- İlgili soru: Bir JavaScript dizisindeki tüm benzersiz değerleri alın (kopyaları kaldırın)

  2. Orijinal dizi arrkorunur ( filterorijinali değiştirmek yerine yeni diziyi döndürür)

  3. filteredDizisi, bütün çiftleri; Bu olabilir , aynı zamanda (burada eden filtre dizi, örneğin 1'den fazla aynı değeri içerir [ 2, 2, 0, 0, -1, 'a', 'a' ])

  4. Yalnızca çoğaltılan değerleri almak istiyorsanız (aynı değerde birden çok çoğaltmaya sahip olmak istemiyorsanız) kullanabilirsiniz [...new Set(filtered)](ES6'nın yalnızca benzersiz değerleri saklayabilen bir nesne kümesi vardır)

Bu yardımcı olur umarım.


5

En kısa vanilya JS :

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

4

İşte çok hafif ve kolay bir yol:

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

En iyi cevap. Ve kullanıcı yinelenen öğeler dizisi istiyorsa, bunun için @ brandon kodu var i = kodları .length; var duplicate = []; while (i--) {if (kodlar .indexOf (kodlar [i])! = i) {if (duplicate.indexOf (kodlar [i]) === -1) {duplicate.push (arr [i]) ; } kodlar. ek yeri (i, 1); }}
Himanshu Shekhar

4

ES6 ile (veya Babel veya Typescipt kullanarak) şunları yapabilirsiniz:

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

https://es6console.com/j58euhbt/


Aynı sözdizimine bağımsız olarak geldim ve bunu bulduğumda bir çözüm olarak eklemek üzereydim. Muhtemelen en ekonomik değil, ama basit.
nize

4

ES6 sözdizimi ile basit kod (sıralı kopya dizisini döndür):

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

Nasıl kullanılır:

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

1
.filter () çok daha kolay olurdu
tocqueville

4

bir astar

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


indx!ilk örnek için ne yapar ?
saylestyler

1
@saylestyler Hehe, bunun anlamı indx !== ...- katı eşitsizlik.
Daria

yalnızca nesne dizileri için eklemeresult.filter((ele,indx) => indx !== result.map(e => e.name).indexOf(ele.name));
x-magix

4

Bu yanıt da yardımcı olabilir, yinelenenleri diziden kaldırmak için js reduce operatörünü / yöntemini kullanır .

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

console.log(result);


3
şimdi sadece new Set([1, 2, 2, 3, 3, 3, 3])kopyaları kaldırmak için yapabiliriz
kimbaudi

3

Aşağıdaki işlev (daha önce bahsedilen eliminateDuplicates işlevinin bir varyasyonu), [[test ”,“ test2 ”,“ test2 ”, 1, 1, 1, 2 girişi için test2,1,7,5 döndürerek hile yapıyor gibi görünüyor. , 3, 4, 5, 6, 7, 7, 10, 22, 43, 1, 5, 8]

Bir JavaScript dizisi hemen hemen her şeyi tutabildiğinden, sorunun JavaScript'te diğer dillerden daha yabancı olduğunu unutmayın. Sıralama kullanan çözümlerin uygun bir sıralama işlevi sağlaması gerekebileceğini unutmayın - Bu yolu henüz denemedim.

Bu özel uygulama (en azından) dize ve sayılar için çalışır.

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

Yalnızca ES5 (yani IE8 ve altı için bir filtre () çoklu dolgusuna ihtiyaç duyar):

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

Bu basit çözümü seviyorum. Ancak kopyaları istiyorsanız, önce bu kopyaları bulmanız ve daha sonra kopya listesini benzersiz yapmanız gerekir. [0, 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3] .sort (). Filtre (işlev (ben, ben, arr) {return (i! == 0 ) && (me == arr [i-1]);}). filtre (işlev (ben, 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));

Bu işlev , sıralama adımını önler ve yinelenenleri zaten mevcut değilse yeni bir diziye göndermek için reduce () yöntemini kullanır.


3

Bu, muhtemelen bir dizideki yinelenenleri, buradaki en işlevlerden 10 kat daha hızlı bir şekilde kalıcı olarak kaldırmanın en hızlı yollarından biridir .

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. Daha fazla: https://stackoverflow.com/a/25082874/2450730

yukarıdaki kodu okuyamazsanız, bir javascript kitabı okuyun veya daha kısa kod hakkında bazı açıklamalar. https://stackoverflow.com/a/21353032/2450730

DÜZENLE Yorumlarda belirtildiği gibi, bu işlev benzersiz bir dizi döndürür, ancak soru yinelenenleri bulmanızı ister. bu durumda, bu işlevde yapılan basit bir değişiklik, kopyaların bir diziye itilmesine izin verir, ardından önceki işlevi kullanmak toUnique, kopyaların kopyalarını kaldırır.

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
"yukarıdaki kodu okuyamıyorsanız sor, bir javascript kitabı okuyun" Bu cevapta çok fazla kod golf var. Değişkenleri a, b, c gibi adlandırmak kodun okunmasını zorlaştırır. Kıvrık parantezleri devam ettirmek daha da kötü hale getirir.
Nehir Williamson

Yanıtlarımın çoğu performans ve alan tasarruflarına dayanıyor (diğer çözümler zaten gönderildi) ... beğenmiyorsanız beğenmedim ... başka javascript öğrenmek, bir js kitabı okuyun ... veya jquery kullanın ... Basit bir çözüm ararsanız daha fazla yanıtınız olur. Gerçekten bir şey öğrenmek istiyorsanız, harf başına kod harfini açıklamaktan mutluluk duyarım. Yorumunuzda gerçek bir soru göremediğim için sanırım cevabımı küçümsemek için bir sebep arıyorsunuz sanırım ... bununla ilgili bir sorunum yok. Gerçek bir soru sorun veya kodumla çalışmayan bir şey söyleyin.
cocco

9
Kodunuzda teknik olarak yanlış bir şey yok. Bununla birlikte, değişkenlerin a, b, c, d, vb. Adlandırılması ve döngüler sırasında zincirleme yapılması kodun okunmasını zorlaştırır. Yani, kod hiçbir şey öğretemez.
Nehir Williamson

3

Öğenin zaten var olup olmadığını test etmek için "içerir" i kullanma.

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 ayrı öğeleri geri verir, ancak verilen sonuca yol açmaz. Lütfen tam doğru kodu girin.
RWC

3

ES6, temel olarak kopyaları kabul etmeyen bir dizi olan Veriyi ayarla yapısını sunar. Set data yapısı ile, bir dizideki kopyaları bulmanın çok kolay bir yolu vardır (sadece bir döngü kullanarak).

İşte kodum

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

Bir Array filtresi kullanarak bunu başarmanın basit bir yolunu buldum

    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

Aşağıdaki mantık daha kolay ve hızlı olacaktır

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

Avantajları:

  1. Tek satır :-P
  2. Verimliliğin artırılmasına yardımcı olan tüm dahili veri yapısı
  3. Daha hızlı

Mantık açıklaması:

  1. Tüm kopyaları kaldırmaya ayarlamak için dönüştürme
  2. Ayarlanan değerler üzerinden yineleme
  3. Her dizi değer kaynak dizisinde "değerler ilk dizini son dizine eşit değil" koşulu için denetlendiğinde = => Sonra yinelenen olarak çıkar 'benzersiz'

Not: map () ve filter () yöntemleri verimli ve daha hızlıdır.


1
Bunu test ettim ... çok hızlı. ve mantıklı .. Keşke bu konuda düşündüm
Michael Rhema
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.