Dapatkan semua nilai non-unik (yaitu: duplikat / lebih dari satu kejadian) dalam sebuah array


418

Saya perlu memeriksa array JavaScript untuk melihat apakah ada nilai duplikat. Apa cara termudah untuk melakukan ini? Saya hanya perlu menemukan nilai duplikatnya - Saya sebenarnya tidak membutuhkan indeks mereka atau berapa kali mereka digandakan.

Saya tahu saya bisa mengulang array dan memeriksa semua nilai lainnya untuk kecocokan, tetapi sepertinya harus ada cara yang lebih mudah.

Pertanyaan serupa:


22
Tampaknya ada bertahun-tahun kebingungan tentang apa yang ditanyakan pertanyaan ini. Saya perlu tahu elemen apa dalam array yang digandakan: "Saya hanya perlu menemukan nilai duplikatnya". Jawaban yang benar TIDAK BISA menghapus duplikat dari array. Itulah kebalikan dari yang saya inginkan: daftar duplikat, bukan daftar elemen unik.
Scott Saunders

Jawaban:


301

Anda bisa mengurutkan array dan kemudian menjalankannya lalu melihat apakah indeks berikutnya (atau sebelumnya) sama dengan saat ini. Dengan asumsi algoritma pengurutan Anda baik, ini harus kurang dari 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)}`);

Dalam hal ini, jika Anda kembali sebagai fungsi untuk duplikat. Ini untuk jenis case yang serupa.

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


10
"Dengan asumsi algoritma sortir Anda bagus, ini seharusnya kurang dari O ^ 2". Khususnya, itu bisa O (n * log (n)).
ESRogs

83
Skrip ini tidak berfungsi dengan baik dengan lebih dari 2 duplikat (mis.arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
Mottie

7
@ swilliams Saya tidak berpikir pedoman mengatakan apa-apa tentang tidak menggunakan i++. Sebaliknya, mereka mengatakan tidak menulis j = i + +j. Dua hal yang berbeda IMHO. Saya pikir i += 1ini lebih membingungkan daripada yang sederhana dan indah i++:)
Danilo Bargen

34
-1 Jawaban ini salah pada banyak tingkatan. Pertama-tama var sorted_arr = arr.sort()tidak berguna: arr.sort()mengubah array asli (yang merupakan masalah dengan sendirinya). Ini juga membuang elemen. (Jalankan kode di atas. Apa yang terjadi pada 9?) Cc @dystroy Solusi yang lebih bersih adalahresults = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
NullUserException

24
Semua orang: pertanyaan diminta untuk menampilkan nilai duplikat, bukan untuk menghapusnya. Tolong jangan mengedit / memecahkan kode untuk mencoba membuatnya melakukan sesuatu yang tidak berusaha untuk dilakukan. Lansiran harus menunjukkan nilai yang digandakan.
Scott Saunders

205

Jika Anda ingin menghilangkan duplikat, coba solusi hebat ini:

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

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


18
Itu kode yang bagus, tapi sayangnya itu tidak melakukan apa yang saya minta.
Scott Saunders

67
Kode di atas (yang milik saya - itu blog saya) membuat Anda cukup dekat. Tweak kecil dan Anda di sana. Pertama-tama, Anda bisa melihat apakah arr.length dan out.length sama. Jika mereka sama, tidak ada elemen duplikat. Tetapi Anda ingin sedikit lebih. Jika Anda ingin "menangkap" dupes saat terjadi, periksa untuk melihat apakah panjang array bertambah setelah obj [arr [i]] = 0 baris. Bagus, eh? :-) Terima kasih atas kata-kata manisnya, Raphael Montanaro.
Nosredna

6
@ MarscoDemaio: Eh, tidak, mengapa kodenya tidak berfungsi dengan spasi? Anda dapat meletakkan apa pun yang Anda suka dalam nama properti - tidak dapat menggunakan sintaksis titik untuk mengaksesnya dengan spasi (atau alat peraga dengan berbagai karakter lain yang akan memecah parsing).
Gijs

4
@ Gijs: +1 Anda benar. Saya tidak tahu itu. Tapi itu masih tidak berfungsi ketika itu adalah array objek.
Marco Demaio

3
Algoritma ini juga memiliki efek samping mengembalikan array yang diurutkan, yang mungkin bukan yang Anda inginkan.
asimetris

166

Ini jawaban saya dari utas rangkap (!):

Saat menulis entri ini 2014 - semua contoh adalah untuk loop atau jQuery. Javascript memiliki alat yang sempurna untuk ini: mengurutkan, memetakan dan mengurangi.

Temukan item duplikat

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

Sintaks yang lebih fungsional:

@ Dmytro-Laptin menunjukkan beberapa kode kode dihapus. Ini adalah versi yang lebih ringkas dari kode yang sama. Menggunakan beberapa trik ES6 dan fungsi urutan yang lebih tinggi:

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
Ini adalah solusi yang saya cari. Jika saya ingin memiliki selusin loop, itu cukup mudah untuk ditulis. Kata kunci dalam OP adalah "efisien".
Josh

@ChristianLandgren, di mana variabel 'dict' dideklarasikan? mungkin 'hitung' harus digunakan sebagai gantinya?
Dmytro Laptin

4
Harap simpan pendapat Anda yang menyesatkan untuk diri sendiri (-1 karena bersikap arogan). Saya pribadi bosan dengan orang-orang yang bingung "pendek" dan "efisien", dan memposting satu kalimat tanpa mempertanyakan pertunjukan. Program pendek dan JS modern TIDAK secara alami lebih baik. Penyalahgunaan kata "efisien" yang khas di sini . Keyakinan naif yang khas di sini (baca komentar berikut). Demo di sini .
daun

1
@leaf - harap simpan saran Anda pada jawaban Anda sendiri. Solusi yang Anda edit tidak dapat dibaca, mungkin performan (mungkin tidak) tetapi meskipun demikian - keterbacaan seringkali lebih penting daripada kinerja menurut saya. Tetapi yang paling penting - jangan hapus kode orang lain untuk menggantikannya dengan kode Anda tanpa alasan.
Christian Landgren

1
Jawaban berbeda, ya, pendapat berbeda, saya kira tidak.
daun

64

Temukan nilai duplikat dalam array

Ini harus menjadi salah satu cara terpendek untuk benar-benar menemukan nilai duplikat dalam array. Seperti yang secara khusus diminta oleh OP, ini tidak menghapus duplikat tetapi menemukannya .

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

Ini tidak perlu disortir atau kerangka kerja pihak ketiga. Itu juga tidak perlu loop manual. Ia bekerja dengan setiap indexOf nilai () (atau lebih jelas: operator perbandingan ketat ) mendukung.

Karena mengurangi () dan indexOf () diperlukan setidaknya IE 9.


7
ES6 panah / versi sederhana / murni:const dupes = items.reduce((acc, v, i, arr) => arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc, [])
ZephDavies

30

Anda dapat menambahkan fungsi ini, atau men-tweak dan menambahkannya ke prototipe Array Javascript:

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

Ini adalah solusi terbaik, tapi hati-hati menambahkannya ke prototipe array, karena itu akan mengacaukan IE jika mengulang nilai-nilai.
Sampsa Suoninen

@RoyTinker perl mendukung mereka juga, tapi saya tidak tahu javascript melakukannya
Luke H

1
Tidak melakukan apa yang diminta OP, kembalikan duplikatnya.
RWC

27

DIPERBARUI: Berikut ini menggunakan strategi gabungan yang dioptimalkan. Ini mengoptimalkan pencarian primitif untuk mendapatkan keuntungan dari hash O (1) waktu pencarian (berjalan uniquepada array primitif adalah O (n)). Pencarian objek dioptimalkan dengan menandai objek dengan id unik saat iterasi melalui sehingga mengidentifikasi objek duplikat juga O (1) per item dan O (n) untuk seluruh daftar. Satu-satunya pengecualian adalah item yang dibekukan, tetapi itu jarang dan fallback disediakan menggunakan array dan 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;
}();

Jika Anda memiliki Koleksi ES6, maka ada versi yang jauh lebih sederhana dan jauh lebih cepat. (shim untuk IE9 + dan browser lain di sini: 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;
    }
  });
}

Betulkah? mengapa menjawab pertanyaan yang telah diselesaikan lebih dari 2 tahun yang lalu?
Rene Pot

3
Saya sedang menjawab pertanyaan lain dan tampaknya secara tidak sengaja mengklik seseorang yang menghubungkan dengan ini, menyebutnya duplikat, dan akhirnya mengkloning jawaban saya dan membingungkan saya sendiri. Saya banyak mengedit barang-barang saya.


16
Saya pikir ini bagus dengan solusi yang berbeda. Tidak masalah bahwa topiknya sudah lama dan terselesaikan karena masih mungkin untuk menghasilkan berbagai cara untuk melakukan ini. Ini masalah khas dalam ilmu komputer.
Emil Vikström

Anda mungkin ingin menyebutkan bahwa ini bergantung pada metode Array ES5 yang tidak diimplementasikan di IE <9.
Tim Down

24

DIPERBARUI: Short one-liner untuk mendapatkan duplikat:

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

Untuk mendapatkan array tanpa duplikat, cukup membalikkan kondisinya:

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

Saya sama sekali tidak memikirkan filter()jawaban lama saya di bawah;)


Ketika semua yang Anda butuhkan adalah memeriksa bahwa tidak ada duplikat seperti yang ditanyakan dalam pertanyaan ini, Anda dapat menggunakan every()metode ini:

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

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

Catatan yang every()tidak berfungsi untuk IE 8 dan di bawah.


1
Tidak melakukan apa yang diminta OP, kembalikan duplikatnya.
RWC

Benar, saya memperbarui jawaban saya untuk memperbaikinya.
Laurent Payot

Solusi royal! thnaks
Jeremy Piednoel

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

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

Ini tampaknya berhasil, tetapi Anda mungkin harus menyertakan beberapa teks yang menjelaskan cara kerjanya.
The DIMM Reaper

1
Tidak akan berfungsi jika ada lebih dari 2 kejadian nilai duplikat.
vasa

1
Ini elegan dan sederhana. Aku menyukainya. Bagi mereka yang ingin mengetahui cara kerjanya, saya telah membuat intisari cara menunjukkan duplikat dan menghilangkan duplikat. Lihat di sini: gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b
Josh

@TheDIMMReaper untuk yang kedua 'a'dalam array, fungsi filter di dalam index == 1, sedangkanself.indexOf('a') == 0
Sergiy Ostrovsky

19

Ini akan memberi Anda apa yang Anda inginkan, Hanya duplikatnya.

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

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


Temukan nilai unik dari 3 array (atau lebih):

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]

Hanya polyfill untuk indeks arrayOf untuk browser lama:

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

Solusi jQuery menggunakan "inArray":

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

alih-alih menambahkan Array.prototype.indexOf


Memberi +1 karena pasti lebih mudah dibaca menggunakan kode Array.indexOf, tetapi sayangnya tampaknya lebih lambat daripada menggunakan loop bersarang sederhana. Bahkan pada peramban yang mengimplementasikan Array.indexOf secara naif seperti FF. Tolong, lihatlah tes-tes ini yang saya lakukan di sini: jsperf.com/array-unique2 dan beri tahu pikiran Anda.
Marco Demaio

@shekhardesigner - jawaban yang diperbarui. "r" adalah larik yang Anda cari
vsync

@vsync Saya harus menginisialisasi, var r = [];agar kode Anda berfungsi. Dan bekerja seperti pesona.
Shekhar K. Sharma

@shekhardesigner - Saya minta maaf atas campuran ini, untuk solusi Array Prototype Anda tidak perlu rvariabel
vsync

2
Tidak melakukan apa yang diminta OP, kembalikan duplikatnya.
RWC

8

Berikut ini adalah solusi sederhana saya dan satu jalur.

Ia mencari bukan elemen unik terlebih dahulu, kemudian membuat array yang ditemukan unik dengan penggunaan Set.

Jadi kami memiliki array duplikat pada akhirnya.

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

Ini proposal saya (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
Ini akan melaporkan bahwa kejadian tunggal undefinedadalah duplikat.
Dem Pilafian

1
@DemPilafian terima kasih, diperbarui
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;});

atau ketika ditambahkan ke 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;});}

Lihat di sini: https://gist.github.com/1305056


1
Fungsi filter harus mengembalikan benar atau salah, bukan elemen itu sendiri. Memfilter array yang mengandung 0 tidak akan mengembalikannya.
mflodin

Juga, saya berasumsi bahwa i&&untuk menghindari keluar dari batas array, tetapi juga berarti bahwa elemen pertama dalam array yang diurutkan tidak akan dimasukkan. Dalam contoh Anda tidak ada 1dalam array yang dihasilkan. Yaitu return i&&v!==o[i-1]?v:0;harusreturn v!==o[i-1];
mflodin

6

Cara cepat dan elegan menggunakan es6 objek yang merusak dan mengurangi

Ini berjalan di O (n) (1 iterasi di atas array) dan tidak mengulangi nilai yang muncul lebih dari 2 kali

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

Inilah solusi paling sederhana yang dapat saya pikirkan:

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

Itu dia.

catatan:

  1. Ini berfungsi dengan angka apa pun termasuk 0, misalnya string dan angka negatif -1- Pertanyaan terkait: Dapatkan semua nilai unik dalam array JavaScript (hapus duplikat)

  2. Array asli arrdipertahankan ( filtermengembalikan array baru alih-alih memodifikasi yang asli)

  3. The filteredarray berisi semua duplikat; itu bisa juga mengandung lebih dari 1 nilai yang sama (misalnya array kita disaring di sini adalah [ 2, 2, 0, 0, -1, 'a', 'a' ])

  4. Jika Anda ingin mendapatkan hanya nilai yang digandakan (Anda tidak ingin memiliki banyak duplikat dengan nilai yang sama) Anda dapat menggunakan [...new Set(filtered)](ES6 memiliki objek Set yang hanya dapat menyimpan nilai-nilai unik)

Semoga ini membantu.


5

Vanilla JS terpendek :

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

4

Ini cara yang sangat ringan dan mudah:

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

Jawaban Terbaik. Dan jika pengguna ingin elemen duplikat array, untuk ini saya memperbarui kode @brandon var i = kode .length; var duplikat = []; while (i--) {if (kode .indexOf (kode [i])! = i) {if (dupate.indexOf (kode [i]) === -1) {dupate.push (arr [i]) ; } codes.splice (i, 1); }}
Himanshu Shekhar

4

Dengan ES6 (atau menggunakan Babel atau Typescipt) Anda cukup melakukan:

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

https://es6console.com/j58euhbt/


Saya datang ke sintaks yang sama, secara mandiri, dan baru saja akan menambahkannya sebagai solusi ketika saya menemukan ini. Mungkin bukan yang paling ekonomis, tetapi sederhana.
nize

4

Kode sederhana dengan sintaks ES6 (mengembalikan array duplikat yang diurutkan):

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

Cara Penggunaan:

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

1
.filter () akan lebih sederhana
tocqueville

4

satu liner

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


apa yang indx!dilakukan untuk contoh pertama?
saylestyler

1
@saylestyler Hehe, ini berarti indx !== ...- ketimpangan yang ketat.
Daria

hanya menambahkan untuk array objekresult.filter((ele,indx) => indx !== result.map(e => e.name).indexOf(ele.name));
x-magix

4

Jawaban ini mungkin juga membantu, memanfaatkan reduce operator / metode js untuk menghapus duplikat dari array.

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

console.log(result);


3
sekarang kita bisa lakukan new Set([1, 2, 2, 3, 3, 3, 3])untuk menghapus duplikat
kimbaudi

3

Fungsi berikut (variasi dari fungsi elimDuplicates yang telah disebutkan) tampaknya melakukan trik, mengembalikan test2,1,7,5 untuk input ["test", "test2", "test2", 1, 1, 1, 2 , 3, 4, 5, 6, 7, 7, 10, 22, 43, 1, 5, 8]

Perhatikan bahwa masalahnya lebih aneh di JavaScript daripada di sebagian besar bahasa lain, karena array JavaScript dapat menampung apa saja. Perhatikan bahwa solusi yang menggunakan penyortiran mungkin perlu menyediakan fungsi penyortiran yang sesuai - Saya belum mencoba rute itu.

Implementasi khusus ini berfungsi untuk (setidaknya) string dan angka.

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

Hanya ES5 (yaitu, ia membutuhkan filter () polyfill untuk IE8 dan di bawah):

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

Saya suka solusi sederhana ini. Jika Anda ingin duplikat, Anda harus terlebih dahulu menemukan duplikat itu, dan kemudian buat daftar duplikat itu unik. [0, 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3] .sort (). Filter (fungsi (saya, i, arr) {return (i! == 0 ) && (me == arr [i-1]);}). filter (fungsi (saya, 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));

Fungsi ini menghindari langkah penyortiran dan menggunakan metode pengurangan () untuk mendorong duplikat ke array baru jika belum ada di dalamnya.


3

Ini mungkin salah satu cara tercepat untuk menghapus duplikat secara permanen dari array 10x kali lebih cepat daripada kebanyakan fungsi di sini. & 78x lebih cepat di 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. Uji: http://jsperf.com/wgu
  2. Demo: http://jsfiddle.net/46S7g/
  3. Lebih lanjut: https://stackoverflow.com/a/25082874/2450730

jika Anda tidak dapat membaca kode di atas tanyakan, baca buku javascript atau di sini ada beberapa penjelasan tentang kode pendek. https://stackoverflow.com/a/21353032/2450730

EDIT Seperti yang dinyatakan dalam komentar fungsi ini mengembalikan array dengan keunikan, namun pertanyaannya meminta untuk menemukan duplikat. dalam hal ini modifikasi sederhana untuk fungsi ini memungkinkan untuk mendorong duplikat ke dalam array, kemudian menggunakan fungsi sebelumnya toUniquemenghapus duplikat dari duplikat.

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
"jika Anda tidak dapat membaca kode di atas, tanyakan, bacalah buku javascript" Ada terlalu banyak kode golf dalam jawaban ini. Memberi nama variabel-variabel seperti a, b, c membuat kode sulit dibaca. Melepaskan kawat keriting membuatnya lebih buruk.
River Williamson

Sebagian besar jawaban saya didasarkan pada kinerja dan penghematan ruang (solusi lain sudah diposting) ... jika Anda tidak suka downvote ... lain belajar javascript, baca buku js ... atau gunakan jquery ... mereka punya lebih banyak jawaban jika Anda mencari solusi sederhana. Jika Anda benar-benar ingin mempelajari sesuatu, saya senang menjelaskan kode huruf per huruf. Karena saya tidak dapat melihat pertanyaan nyata dalam komentar Anda, saya kira Anda hanya mencari motif untuk menurunkan jawaban saya .... terus ... saya tidak punya masalah dengan itu. Ajukan pertanyaan nyata atau beri tahu saya sesuatu yang tidak berfungsi dengan kode saya.
cocco

9
Tidak ada yang salah secara teknis dengan kode Anda. Yang mengatakan, penamaan variabel a, b, c, d, dll. Dan rantai sementara loop membuat kode sulit dibaca. Jadi, kode gagal mengajarkan apa pun.
River Williamson

3

Menggunakan "termasuk" untuk menguji apakah elemen sudah ada.

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>


Kode memang memberikan kembali elemen yang berbeda, tetapi tidak mengarah pada hasil yang diberikan. Harap berikan kode yang benar lengkap.
RWC

3

ES6 menawarkan struktur data Set yang pada dasarnya adalah array yang tidak menerima duplikat. Dengan struktur Set data, ada cara yang sangat mudah untuk menemukan duplikat dalam array (hanya menggunakan satu loop).

Ini kode saya

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

Saya baru saja menemukan cara sederhana untuk mencapai ini menggunakan filter 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

Logika berikut akan lebih mudah dan lebih cepat

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

Keuntungan :

  1. Baris tunggal :-P
  2. Semua struktur data bawaan membantu meningkatkan efisiensi
  3. Lebih cepat

Deskripsi Logika:

  1. Konversi ke set untuk menghapus semua duplikat
  2. Iterasi melalui nilai yang ditetapkan
  3. Dengan setiap nilai cek ditetapkan dalam array sumber untuk kondisi "nilai indeks pertama tidak sama dengan indeks terakhir" ==> Kemudian disimpulkan sebagai duplikat selain itu 'unik'

Catatan: metode map () dan filter () lebih efisien dan lebih cepat.


1
Menguji ini ... sangat cepat. dan itu masuk akal .. seandainya saya memikirkannya
Michael Rhema
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.