Как сделать массив уникальным js

Добавил пользователь Валентин П.
Обновлено: 04.10.2024

У меня есть массив чисел, которые мне нужно убедиться, уникальны. Я нашел фрагмент кода ниже в Интернете, и он отлично работает, пока в нем не будет нуля. Я нашел этот другой script здесь на SO, который выглядит почти так же, как и он, но это не подводит.

Итак, чтобы помочь мне учиться, может кто-нибудь помочь мне определить, где прототип script идет не так?

Дополнительные ответы от дублирующего вопроса:

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

С JavaScript 1.6/ECMAScript 5 вы можете использовать собственный метод filter массива следующим образом, чтобы получить массив с уникальными значениями:

filter собственных методов будет проходить через массив и оставить только те записи, которые передают данную функцию обратного вызова onlyUnique .

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

Это решение работает без дополнительной библиотеки, такой как jQuery или prototype.js.

Он также работает для массивов со смешанными типами значений.

Для старых браузеров ( filter собственных методов и indexOf вы можете найти работу в документации MDN для фильтра и indexOf.

Если вы хотите сохранить последнее вхождение значения, просто замените indexOf на lastIndexOf .

С ES6 это может быть сокращено:

Спасибо Камило Мартину за намек в комментарии.

ES6 имеет собственный объект. Set для хранения уникальных значений. Чтобы получить массив с уникальными значениями, вы можете сделать это сейчас:

Конструктор Set принимает итерируемый объект, такой как Array, и оператор спреда . преобразует набор обратно в массив. Спасибо Lukas Liese за намек в комментарии.

Обновленный ответ для ES6/ES2015. Используя Set, однострочное решение:

Как предложил le_m, это также можно сократить с помощью оператора распространения, например

Я разделил все ответы на 4 возможных решения:

  • Используйте новую функцию ES6: [. new Set( [1, 1, 2] )];
  • Использовать объект < >для предотвращения дублирования
  • Использовать вспомогательный массив [ ]
  • Используйте filter + indexOf

Здесь примеры кодов, найденные в ответах:

И я подумал, какой из них быстрее. Я сделал образец Google Sheet для тестирования функций. Примечание. ECMA 6 недоступен в Google Таблицах, поэтому я не могу его протестировать.

введите описание изображения здесь

Здесь результат тестов:

Я ожидал увидеть, что код с использованием объекта < >будет побежден, потому что он использует хеш. Поэтому я рад, что тесты показали наилучшие результаты для этого алгоритма в Chrome и IE. Благодаря @rab для кода.

Вы также можете использовать underscore.js.

С синтаксисом ES6

list = list.filter((x, i, a) => a.indexOf(x) == i)

введите описание изображения здесь

С синтаксисом ES5

Совместимость браузера: IE9 +

С тех пор я нашел хороший метод, который использует jQuery

Примечание: этот код был вытащен из Paul Irish duck punching post - Я забыл отдать должное: P

Самое короткое решение с ES6: [. new Set( [1, 1, 2] )];

Или, если вы хотите изменить прототип Array (как в исходном вопросе):

EcmaScript 6 частично реализована в современных браузерах в настоящий момент (август 2015 г.), но Babel стал очень популярным для пересылки ES6 (и даже ES7) обратно в ES5. Таким образом, вы можете написать код ES6 сегодня!

Если вам интересно, что означает . , он называется оператором распространения . Из MDN: "Оператор спрединга позволяет расширять выражение в местах, где ожидаются несколько аргументов (для вызовов функций) или нескольких элементов (для литералов массива)". Поскольку Set является итерируемым (и может иметь только уникальные значения), оператор с расширением будет расширять набор, чтобы заполнить массив.

Ресурсы для обучения ES6:

  • Изучение ES6 доктором Акселем Раушмайером
  • Поиск "ES6" из еженедельных бюллетеней JS
  • ES6 в деталях статей из блога Mozilla Hacks

Самое простое решение:

Самый простой и самый быстрый (в Chrome) способ сделать это:

Просто просматривает каждый элемент массива, проверяет, находится ли этот элемент в списке, а если нет, нажмите на массив, который возвращается.

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

Версия, отличная от прототипа:

Сортировка

При необходимости также сортировать массив, самое быстрое:

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

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

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

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

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

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

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

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

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

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

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

то есть: 80 000 оп/с против 3500 000 оп/с

ios: 18 000 оп/с против 170 000 оп/с

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

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

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

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

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

Подобный вопрос:

ОТВЕТЫ

Ответ 1

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

Ответ 2

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

Ответ 3

Это мой ответ из дубликата темы (!):

При написании этой записи 2014 - все примеры были for-loop или jQuery. Javascript имеет идеальные инструменты для этого: сортировать, отображать и уменьшать.

Найти дубликаты

Ответ 4

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

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

Ответ 5

Вы можете добавить эту функцию или настроить ее и добавить в прототип Javascript Array:

Ответ 6

ОБНОВЛЕНО: в следующей используется оптимизированная комбинированная стратегия. Он оптимизирует примитивный поиск, чтобы извлечь выгоду из времени поиска хэш-ов (1) (запуск unique в массиве примитивов - O (n)). Поиск объектов оптимизируется путем пометки объектов с уникальным идентификатором во время итерации, так что идентификация повторяющихся объектов также O (1) для каждого элемента и O (n) для всего списка. Единственное исключение - это элементы, которые были заморожены, но они редки, и резервное копирование предоставляется с использованием массива и indexOf.

Ответ 7

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

Ответ 8

Ответ 9

Ответ 10

ОБНОВЛЕНО: Короткий однострочный, чтобы получить дубликаты:

Чтобы получить массив без дубликатов, просто измените условие:

Я просто не думал о filter() в моем старом ответе ниже;)

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

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

Ответ 11

Вот мое простое и однострочное решение.

Сначала он ищет не уникальные элементы, а затем делает найденный массив уникальным с использованием Set.

Массивы в JavaScript являются объектами, которые содержат, как правило, однотипные элементы, т.е. только числа, строки, булевы величины ( true или false ) или другие объекты, в том числе и другие массивы. Эти элементы расположены друг за другом, т.е. упорядоченно. Порядок расположения элементов определяется индексами, т.е. номерами, с помощью которых можно обращаться, получать и изменять элементы массива.

Особенности массива в JavaScript

  • Объявление массива выделяет последовательные блоки памяти.
  • Каждый блок памяти представляет элемент массива.
  • Элементы массива идентифицируются уникальным целым числом, называемым индексом / индексом элемента.
  • Массивы также, как и переменные, должны быть объявлены до их использования.
  • Инициализация массива заключается в заполнении массива элементами.

Объявление массива

Для того чтобы объявить массив, используются 2 способа:
1. С помощью литерала массива:

2. Используя встроенный объект Array:

Посмотрим, что будет выведено:

В консоли мы увидим такое отображение массивов:

Объявление массива

Пустой массив, объявленный любым способом, представлен в виде двух квадратных скобок. Массив из 5 элементов с неопределенными значениями показан, как массив из 5 пустых (empty) ячеек. Массивы, заполненные элементами, выводятся с указанием их количества и значениями самих элементов.

Длина массива

Часто используемым свойством массива является его длина (length). Она показывает количество элементов:

В результате мы получим цифру. В нашем примере это 5.

Примечание: слово length первоначально довольно сложно для написания. Очень легко написать его так: lenght или legnth, однако это будет неверно с точки зрения JavaScript. Поэтому имеет смысл использовать для написания кода текстовые редакторы, где заложены подсказки.

Обращение к элементам массива

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

Давайте посмотрим на результат:

Вы можете увидеть, что 2 первых элемента массива изменились, остальные 3 остались неизменными, далее появились 2 пустых (empty) элемента и последний элемент имеет значение 15. Т.е. наш массив не только изменился с точки зрения значений элементов, он еще и увеличился в размере.

Элементы массива

Использование цикла for для перебора массива

Чаще всего необходимо изменить не только один-два элемента массива, а их все. Для этого с очень давних времен используется цикл for . Например, нам необходимо добавить ко всем элементам числового массива число 5:

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

Результат перебора массива циклом for

Мы можем также использовать метод forEach() для перебора и манипулирования элементами массива.

Перебираем элементы с методом forEach()

Метод arr.forEach() позволяет запускать функцию для каждого элемента массива, таким образом позволяя перебрать элементы массива аналогично тому, как это делает цикл for . Метод forEach() выполняет заданную функцию (ее еще называют callback ) один раз для каждого элемента, находящегося в массиве в порядке возрастания, т.е. перебирает элементы от нулевого индекса до последнего. Функция callback не будет вызвана для удалённых или пропущенных элементов массива. Для тех элементов, которые присутствуют в массиве и имеют значение undefined, она тоже сработает.

Синтаксис метода forEach() имеет 3 варианта в зависимости от количества нужных вам аргументов (от одного до трех).

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

Как получить все неуникальные значения в массиве JavaScript?

Иногда бывает нужно получить все повторяющиеся значения из массива JavaScript.

В этой статье мы рассмотрим способы получения всех неуникальных значений в массиве JavaScript.

Array.prototype.filter

Один из таких способов связан с использованием метода filter массива JavaScript для возвращения массива, соответствующего заданному условию.

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

Задействуя метод filter вместе с вызовом метода indexOf в функции обратного вызова, мы проверяем, является ли встреченный элемент первым.

Для этого в массиве, в котором вызывается filter , вызываем indexOf , получаемый из третьего параметра функции обратного вызова.

Затем проверяем, совпадает ли возвращаемый индекс с тем, которому соответствует итерируемый элемент.

Например, напишем следующее:

Затем вызываем filter с функцией обратного вызова, которая принимает параметры e , index и arr , где:

  • e — это элемент, по которому выполняется итеративный обход;
  • index — это индекс элемента e ;
  • arr — это массив, в котором вызывается filter .

Мы вызываем indexOf в arr с аргументом e , чтобы вернуть индекс первого встреченного элемента e в массиве arr .

Несовпадение ​возвращаемого индекса с index свидетельствует о том, что это встреченное значение не первое.

Следовательно, duplicates (повторяющиеся значения) — это [2, 4] , так как они дублируются в массиве.

Подсчет элементов

Посчитаем элементы в массиве, создав собственный объект для задания значения счетчика:

Вызываем map для сопоставления каждой записи объекту со счетчиком count , имеющим значение 1, и со значением элемента массива val .

Затем вызываем reduce для создания объекта со счетчиком каждого элемента, где каждый элемент будет ключом.

Делаем это, присваивая счетчик из a[b.val] с (a[b.val] || 0) + b.count .

В b.count имеется новый счетчик.

И возвращаем a , где содержатся все произведенные подсчеты.

Второй аргумент — пустой объект, поэтому создаем объект в конце.

Затем для получения повторяющихся значений мы берем все ключи со значением больше 1.

Для этого вызываем Object.entries в obj .

После чего вызываем filter с функцией обратного вызова для возвращения любых записей со значением val больше 1.

val — это значение свойства объекта.

Получаем тот же результат, что и в предыдущем примере для duplicates (повторяющихся значений).

Заключение

Для получения из массива повторяющихся значений используются различные методы массивов и объектов. Мы рассмотрели лишь малую их часть.

Читайте также: