Как сделать массив уникальным js
У меня есть массив чисел, которые мне нужно убедиться, уникальны. Я нашел фрагмент кода ниже в Интернете, и он отлично работает, пока в нем не будет нуля. Я нашел этот другой 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 . В результате использования цикла мы получили измененный массив.
Мы можем также использовать метод forEach() для перебора и манипулирования элементами массива.
Перебираем элементы с методом forEach()
Метод arr.forEach() позволяет запускать функцию для каждого элемента массива, таким образом позволяя перебрать элементы массива аналогично тому, как это делает цикл for . Метод forEach() выполняет заданную функцию (ее еще называют callback ) один раз для каждого элемента, находящегося в массиве в порядке возрастания, т.е. перебирает элементы от нулевого индекса до последнего. Функция callback не будет вызвана для удалённых или пропущенных элементов массива. Для тех элементов, которые присутствуют в массиве и имеют значение undefined, она тоже сработает.
Синтаксис метода forEach() имеет 3 варианта в зависимости от количества нужных вам аргументов (от одного до трех).
Вариант 1: функция вызывается с одним обязательным аргументом, который позволяет манипулировать значением элемента. В примере мы используем значение каждого элемента массива, чтобы разделить его на 4 и вывести полученный результат.
Иногда бывает нужно получить все повторяющиеся значения из массива 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 (повторяющихся значений).
Заключение
Для получения из массива повторяющихся значений используются различные методы массивов и объектов. Мы рассмотрели лишь малую их часть.
Читайте также: