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

Мне нужно проверить массив 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)); 
  • Что вызывает исключение java.lang.ArrayIndexOutOfBoundsException и как его предотвратить?
  • Как объявить 2d-массив в C ++ с помощью new?
  • Поиск массивов «не найден», даже если он найден
  • Как найти «sizeof» (указатель, указывающий на массив)?
  • Как удалить объекты из массива в Java?
  • Как проверить, находится ли элемент в массиве
  • Как получить доступ к многомерному массиву и управлять им с помощью имен / путей ключа?
  • Синтаксис инициализации массива, если не в объявлении
  • Как преобразовать ArrayList, содержащий целые числа в примитивный массив int?
  • Сохранение заказа с помощью LINQ
  • Где Java-массив Array indexOf?
  • Как найти индекс элемента списка в Swift?
  • Interesting Posts

    Плохая производительность в Windows 7 с плохими секторами

    Удаленный рабочий стол Windows с автоматической сменой разрешения

    Сообщите Thunderbird об усечении или обертке строк при отправке электронной почты.

    В Windows 10, почему некоторые программы масштабируются на втором мониторе 2.1, но не контролируют 2.2?

    Является ли RAID 1 на домашнем ПК полезным?

    Команда Linux для возврата числа бит (32 или 64)?

    Зацикливание по спирали

    Windows XP – синий экран

    Как закрыть вкладку ConEmu без подтверждения?

    В OS X как добавить переменную среды, загружаемую во время запуска?

    Как найти последнюю строку, содержащую данные на листе Excel с макросом?

    Как узнать, какая программа взяла контроль над клавишей Print Screen?

    Форматировать разблокированные ячейки с VBA в защищенном листе, но не заблокированные ячейки

    Окно удаленного рабочего стола вернется к ярлыку хоста

    Разница между программами, скомпилированными для разных ОС

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