Получите все неединственные значения (то есть: дублировать / более одного вхождения) в массиве

Мне нужно проверить массив JavaScript, чтобы увидеть, есть ли повторяющиеся значения. Какой самый простой способ сделать это? Мне просто нужно найти, какие дублированные значения – мне действительно не нужны их индексы или сколько раз они дублируются.

Я знаю, что могу перебирать массив и проверять все остальные значения для соответствия, но похоже, что должен быть более простой способ. Есть идеи? Благодаря!

Аналогичный вопрос:

  • Получите все уникальные значения в массиве (удалите дубликаты)

30 Solutions collect form web for “Получите все неединственные значения (то есть: дублировать / более одного вхождения) в массиве”

Вы можете отсортировать массив, а затем запустить его, а затем посмотреть, совпадает ли следующий (или предыдущий) индекс с текущим. Предполагая, что ваш алгоритм сортировки хорош, это должно быть меньше O (n 2 ):

var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7]; var 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) var results = []; for (var i = 0; i < sorted_arr.length - 1; i++) { if (sorted_arr[i + 1] == sorted_arr[i]) { results.push(sorted_arr[i]); } } console.log(results); 

Если вы хотите использовать дубликаты, попробуйте это отличное решение:

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

Источник: http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates/

Это мой ответ из повторяющейся нити (!):

Очень устал видеть все плохие примеры с for-loops или jQuery. Javascript имеет идеальные инструменты для этого в наши дни: сортировка, карта и сокращение.

Найти дубликаты товаров

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

Более функциональный синтаксис:

@ Dmytro-Laptin указал, что код кода будет удален. Это более компактная версия того же кода. Использование некоторых трюков ES6 и функций более высокого порядка:

 const names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl'] const count = names => names.reduce((a, b) => Object.assign(a, {[b]: (a[b] || 0) + 1}), {}) 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' ] 

Использование Function.prototype.bind:

  // prep const arr = Array.from('Learn more javascript dude'); const counter = (prev, next) => Object.assign(prev, { [next] : (prev[next] || 0) + 1 }); const singles = function(key){ return this[key] === 1 }; const multiples = function(key){ return this[key] > 1 }; // work const counted = arr.reduce(counter, {}); const filtered = Object.keys(counted).filter(multiples.bind(counted)); //[ "e", "a", "r", " ", "d" ] console.log(filtered); 

Вы можете добавить эту функцию или настроить ее и добавить в прототип массива 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); 

ОБНОВЛЕНО: Следующая страtagsя использует оптимизированную комбинированную страtagsю. Он оптимизирует примитивные поисковые запросы, чтобы извлечь выгоду из времени поиска hash-ов (1) (запуск unique массива примитивов – O (n)). Поиск объектов оптимизируется путем пометки объектов с уникальным идентификатором во время итерации, так что идентификация повторяющихся объектов также O (1) для каждого элемента и O (n) для всего списка. Единственное исключение – это элементы, которые заморожены, но они редки, и резервное копирование предоставляется с использованием массива и 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; }(); 

Если у вас есть Коллекции ES6, то есть намного более простая и значительно более быстрая версия. (прокладка для IE9 + и других браузеров здесь: 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; } }); } 

Найти повторяющиеся значения в массиве

Это должно быть одним из самых коротких способов фактического поиска повторяющихся значений в массиве. Как специально просил OP, это не удаляет дубликаты, а находит их .

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

Это должно получить то, что вы хотите, просто дубликаты.

 function find_duplicates(arr) { var len=arr.length, out=[], counts={}; for (var i=0;i= 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. 

использование underscore.js

 function hasDuplicate(arr){ return (arr.length != _.uniq(arr).length); } 
 var a = ["a","a","b","c","c"]; a.filter(function(value,index,self){ return (self.indexOf(value) !== index )}) 
 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;}); 

или при добавлении в prototyp.chain of 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;});} 

См. Здесь: https://gist.github.com/1305056

Когда вам нужно только проверить, нет ли дубликатов, как задано в этом вопросе, вы можете использовать метод every() :

 [1, 2, 3].every(function(elem, i, array){return array.lastIndexOf(elem) === i}) // true [1, 2, 1].every(function(elem, i, array){return array.lastIndexOf(elem) === i}) // false 

Обратите внимание, что every() не работает для IE 8 и ниже.

Я использую lastIndexOf() потому что он может быть более эффективным, чем indexOf() если обратные вызовы функции, сделанные every() , выполняются в указательном порядке, но это не доказано.

В CoffeeScript я использую это:

 Array::duplicates = -> not @every((elem, i, array) -> array.lastIndexOf(elem) is i) [1, 2, 3].duplicates() // false [1, 2, 1].duplicates() // true 

Найдите уникальные значения из 3 массивов (или более):

 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], unique = arr.concat(arr2, arr3).unique(); console.log(unique); // [22, 50, 12, 511, 2, 1, 9, 5, 8, 7, 3, 6, 4] 

Просто полипол для массива indexOf для старых браузеров:

 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 с использованием «inArray»:

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

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

Простой код с синтаксисом ES6 (возвращаемый отсортированный массив дубликатов):

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

Как использовать:

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

Следующая функция (вариант уже упомянутой функции устранения дубликатов), похоже, делает трюк, возвращая test2,1,7,5 для ввода [«test», «test2», «test2», 1, 1, 1, 2 , 3, 4, 5, 6, 7, 7, 10, 22, 43, 1, 5, 8]

Обратите внимание, что проблема в JavaScript более странная, чем в большинстве других языков, потому что массив JavaScript может содержать практически все. Обратите внимание, что для решений, использующих сортировку, может потребоваться соответствующая функция сортировки – я еще не пробовал этот маршрут.

Эта конкретная реализация работает для (по крайней мере) строк и чисел.

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

Здесь очень легкий и легкий способ:

 var codes = dc_1.split(','); var i = codes.length; while (i--) { if (codes.indexOf(codes[i]) != i) { codes.splice(i,1); } } 
 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)); 

Использование «includes» для проверки того, существует ли элемент уже.

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

Array with duplicates

[1, 1, 4, 5, 5]

Array with distinct elements

[1, 4, 5]

duplicate values are

[1, 5]

ES6 предлагает структуру данных Set, которая в основном представляет собой массив, который не принимает дубликаты. С помощью структуры данных Set существует очень простой способ найти дубликаты в массиве (используя только один цикл).

Вот мой код

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

С ES6 (или с помощью Babel или Typescipt) вы можете просто сделать:

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

https://es6console.com/j58euhbt/

Я просто вычислил простой способ добиться этого, используя фильтр 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); 

Быстрый и элегантный способ использования деструкции объектов es6 и уменьшения

Он работает в O (n) (1 итерация по массиву) и не повторяет значения, которые появляются более чем в 2 раза

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

Просто добавим теорию к сказанному выше.

Поиск дубликатов имеет нижнюю границу O (n * log (n) в модели сравнения. Теоретически, вы не можете сделать ничего лучше первой сортировки, а затем перебирать список, последовательно удаляя любые дубликаты, которые вы найдете.

Если вы хотите найти дубликаты в линейном (O (n)) ожидаемом времени, вы можете hash каждого элемента списка; если есть столкновение, удалите / пометьте его как дубликат и продолжайте.

ES5 (т. Е. Для фильтра IE8 и ниже требуется фильтр ()):

 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] ); }); 
 var input = ['a', 'b', 'a', 'c', 'c'], duplicates = [], i, j; for (i = 0, j = input.length; i < j; i++) { if (duplicates.indexOf(input[i]) === -1 && input.indexOf(input[i], i+1) !== -1) { duplicates.push(input[i]); } } console.log(duplicates); 

Я думаю, что ниже – самый простой и быстрый способ O (n) выполнить то, что вы спросили:

 function getDuplicates( arr ) { var i, value; var all = {}; var duplicates = []; for( i=0; i 

Или для ES5 или выше:

 function getDuplicates( arr ) { var all = {}; return arr.reduce(function( duplicates, value ) { if( all[value] ) { duplicates.push(value); all[value] = false; } else if( typeof all[value] == "undefined" ) { all[value] = true; } return duplicates; }, []); } 

Модификация решения @ RaphaelMontanaro, заимствования из блога @ Nosredna, вот что вы могли бы сделать, если хотите просто идентифицировать повторяющиеся элементы из своего массива.

 function identifyDuplicatesFromArray(arr) { var i; var len = arr.length; var obj = {}; var duplicates = []; for (i = 0; i < len; i++) { if (!obj[arr[i]]) { obj[arr[i]] = {}; } else { duplicates.push(arr[i]); } } return duplicates; } 

Спасибо за элегантное решение, @Nosredna!

Мне не понравилось большинство ответов.

Зачем? Слишком сложный, слишком много кода, неэффективный код и многие не отвечают на вопрос, который заключается в том, чтобы найти дубликаты (а не давать массив без дубликатов).

Следующая функция возвращает все дубликаты:

 function GetDuplicates(arr) { var i, out=[], obj={}; for (i=0; i < arr.length; i++) obj[arr[i]] == undefined ? obj[arr[i]] ++ : out.push(arr[i]); return out; } 

Потому что большую часть времени бесполезно возвращать ВСЕ дубликаты, но просто чтобы указать, какие повторяющиеся значения существуют. В этом случае вы возвращаете массив с уникальными дубликатами 😉

 function GetDuplicates(arr) { var i, out=[], obj={}; for (i=0; i < arr.length; i++) obj[arr[i]] == undefined ? obj[arr[i]] ++ : out.push(arr[i]); return GetUnique(out); } function GetUnique(arr) { return $.grep(arr, function(elem, index) { return index == $.inArray(elem, arr); }); } 

Может быть, кто-то другой думает так же.

Я предпочитаю функциональный способ сделать это.

 function removeDuplicates(links) { return _.reduce(links, function(list, elem) { if (list.indexOf(elem) == -1) { list.push(elem); } return list; }, []); } 

В этом случае используется символ подчеркивания, но у Array также есть функция reduce

Чтобы решить вышеописанную сложность времени O (n) (без сортировки).

 var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7]; var obj={}; for(var i=0;i1){ result.push(Number(key)) // change this to result.push(key) to find duplicate strings in an array } } console.log(result) 

Вероятно, это один из самых быстрых способов удаления навсегда дубликатов из массива в 10 раз быстрее, чем большинство функций здесь. & 78 раз быстрее в 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); в 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); , 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. Тест: http://jsperf.com/wgu
  2. Демо: http://jsfiddle.net/46S7g/
  3. Подробнее: https://stackoverflow.com/a/25082874/2450730

если вы не можете прочитать код, указанный выше, прочитайте javascript книгу или вот некоторые объяснения относительно более короткого кода. https://stackoverflow.com/a/21353032/2450730

EDIT Как указано в комментариях, эта функция возвращает массив с uniques, однако вопрос требует найти дубликаты. в этом случае простая модификация этой функции позволяет вывести дубликаты в массив, а затем использовать предыдущую функцию toUnique удаляет дубликаты дубликатов.

 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)); в 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)); , 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)); 
  • Есть ли максимальный предел длины массива в C ++?
  • С массивами, почему это так, == 5 ?
  • Как найти «sizeof» (указатель, указывающий на массив)?
  • массив фиксированной длины typedef
  • Как создать общий массив в Java?
  • Разделить строку на массив в Bash
  • Как найти длину массива?
  • как разрешить массив с сильными параметрами
  • Создать матрицу, содержащую все комбинации элементов, взятых из n векторов
  • Синтаксис инициализации массива, если не в объявлении
  • Является ли массив примитивным типом или объектом (или чем-то еще полностью)?
  • Interesting Posts

    Как переместить загрузочный сектор на другой диск?

    «В настоящий момент точка останова не будет удалена. Исходный код отличается от исходного. «Что это значит?

    Используйте проводной Ethernet для сетевых дисков, но Wi-Fi для Интернета

    Это плохо для дефрагментации ssd? Или просто бессмысленно?

    Цветной вывод ls в соответствии с расширением файла

    Разрешение на разрешение прошивки Android?

    Как остановить wuauserv

    Как я могу использовать jQuery в сценариях Greasemonkey в Google Chrome?

    Мой ноутбук не будет спать, когда я закрываю крышку

    Рассчитать количество рабочих дней между двумя датами?

    C ++ сортировка и отслеживание индексов

    Пользователь ” не может получить доступ с ссылкой на экземпляр

    Использование диска Windows 8 на 100%

    Установите планировщик окон, чтобы запланировать открытие веб-сайта, веб-страницы или закладки

    Перерыв при исключении исключения

    Давайте будем гением компьютера.