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

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

ТОЛЬКО ЭФФЕКТИВНОСТЬ! этот код, вероятно, в 10 раз быстрее, чем все приведенные здесь *, работает во всех браузерах, а также имеет минимальное влияние на память ….

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

 var array=[1,2,3,4,5,6,7,8,9,0,1,2,1]; 

тогда вы можете попробовать это

 var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1]; function toUnique(a, b, c) { //array,placeholder,placeholder b = a.length; while (c = --b) while (c--) a[b] !== a[c] || a.splice(c, 1); return a // not needed ;) } console.log(toUnique(array)); //[3, 4, 5, 6, 7, 8, 9, 0, 2, 1] 

Я придумал эту функцию, читая эту статью …

http://www.shamasis.net/2009/09/fast-algorithm-to-find-unique-items-in-javascript-array/

Мне не нравится цикл for. он имеет много параметров. Мне нравится цикл while—. while — самый быстрый цикл во всех браузерах, кроме того, который нам всем так нравится … chrome.

Во всяком случае, я написал первую функцию, которая использует while. И да, это немного быстрее, чем функция, найденная в статье. Но недостаточно. unique2()

Следующий шаг использовать современные JS. Object.keys Я заменил другой цикл for на Object.keys в js1.7 … немного быстрее и короче (в chrome в 2 раза быстрее);). Недостаточно!. unique3() .

в этот момент я думал о том, что мне действительно нужно в МОЕЙ уникальной функции. мне не нужен старый массив, я хочу быструю функцию. так что я использовал 2 в то время как петли сплайс. unique4()

Бесполезно говорить, что я был впечатлен.

хром: обычные 150 000 операций в секунду подскочили до 1 800 000 операций в секунду.

то есть: 80 000 операций / с против 3 500 000 операций / с

IOS: 18 000 операций / с против 170 000 операций / с

сафари: 80 000 оп / с против 6 000 000 оп / с

Доказательство http://jsperf.com/wgu или лучше использовать console.time … microtime … что угодно

unique5() просто показывает вам, что происходит, если вы хотите сохранить старый массив.

Не используйте Array.prototype если вы не знаете, что делаете. Я только что сделал много копий и прошлого. Используйте Object.defineProperty(Array.prototype,...,writable:false,enumerable:false}) если вы хотите создать собственный prototype.example: https://stackoverflow.com/a/20463021/2450730

Демо http://jsfiddle.net/46S7g/

ПРИМЕЧАНИЕ: ваш старый массив уничтожается / становится уникальным после этой операции.

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

некоторые используют indexOf … не … http://jsperf.com/dgfgghfghfghghgfhgfhfghfhgfh

для пустых массивов

 !array.length||toUnique(array); 

§

Дедупликация обычно требует оператора равенства для данного типа. Однако использование функции eq мешает нам использовать Set для эффективного определения дубликатов, потому что Set возвращается к === . Как вы точно знаете, === не работает для ссылочных типов. Так что мы добры, если застряли, верно?

Выходом является просто использование функции-трансформера, которая позволяет нам преобразовывать (эталонный) тип в нечто, что мы можем на самом деле искать, используя Set . Например, мы могли бы использовать хеш-функцию или JSON.stringify структуру данных, если она не содержит каких-либо функций.

Часто нам нужен только доступ к свойству, которое мы затем можем сравнить вместо ссылки на Object .

Вот два комбинатора, которые отвечают этим требованиям:

 const dedupeOn = k ={amp}gt; xs ={amp}gt; { const s = new Set(); return xs.filter(o ={amp}gt; s.has(o[k]) ? null : (s.add(o[k]), o[k])); }; const dedupeBy = f ={amp}gt; xs ={amp}gt; { const s = new Set(); return xs.filter(x ={amp}gt; { const r = f(x); return s.has(r) ? null : (s.add(r), x); }); }; const xs = [{foo: "a"}, {foo: "b"}, {foo: "A"}, {foo: "b"}, {foo: "c"}]; console.log( dedupeOn("foo") (xs)); // [{foo: "a"}, {foo: "b"}, {foo: "A"}, {foo: "c"}] console.log( dedupeBy(o ={amp}gt; o.foo.toLowerCase()) (xs)); // [{foo: "a"}, {foo: "b"}, {foo: "c"}] 

С этими комбинаторами мы чрезвычайно гибки в решении всех видов проблем дедупликации. Это не быстрый подход, но самый выразительный и самый общий.

§

Многие люди уже упоминали об использовании …

 [...new Set(arr)]; 

И это отличное решение, но я предпочитаю решение, которое работает с .filter . На мой взгляд, фильтр — более естественный способ получения уникальных значений. Вы эффективно удаляете дубликаты, а удаление элементов из массива — это именно то, для чего предназначен фильтр. Это также позволяет вам .filter вызовы .map , .reduce и других .filter . Я разработал это решение …

 const unique = () ={amp}gt; { let cache; return (elem, index, array) ={amp}gt; { if (!cache) cache = new Set(array); return cache.delete(elem); }; }; myArray.filter(unique()); 

Предостережение в том, что вам нужно закрытие, но я думаю, что это достойный компромисс. С точки зрения производительности, он более производительный, чем другие опубликованные мной решения, использующие .filter , но хуже, чем [...new Set(arr)] .

Смотрите также мой пакет github youneek

Понравилась статья? Поделиться с друзьями:
JavaScript & TypeScript
Adblock
detector