У меня есть два массива JavaScript:
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
Я хочу вывод:
var array3 = ["Vijendra","Singh","Shakya"];
В выходном массиве должны быть удалены повторяющиеся слова.
Как объединить два массива в JavaScript, чтобы я получал только уникальные элементы из каждого массива в том же порядке, в котором они были вставлены в исходные массивы?
javascript
arrays
merge
Vijjendra
источник
источник
Ответы:
Чтобы просто объединить массивы (без удаления дубликатов)
Использование версии ES5
Array.concat
:ES6 версия использования деструктуризация
Поскольку не существует «встроенного» способа удаления дубликатов (на самом деле в ECMA-262 это
Array.forEach
было бы неплохо), мы должны сделать это вручную:Затем, чтобы использовать это:
Это также сохранит порядок массивов (т. Е. Сортировка не требуется).
Так как многие раздражаются по поводу увеличения прототипов
Array.prototype
иfor in
циклов, вот менее инвазивный способ его использования:Для тех, кому посчастливилось работать с браузерами, в которых доступен ES5, вы можете использовать
Object.defineProperty
вот так:источник
[a, b, c]
и[x, b, d]
быть массивов (предположим, кавычки). Конкат дает[a, b, c, x, b, d]
. Не будет ли уникальный () вывод[a, c, x, b, d]
. Это не сохраняет порядок, я думаю - я считаю, что ОП хочет[a, b, c, x, d]
for ... in
сhasOwnProperty
в этом случае метод прототипа является штрафС Underscore.js или Lo-Dash вы можете сделать:
http://underscorejs.org/#union
http://lodash.com/docs#union
источник
underscore.flatten()
, что лучше, чем объединение в том, что он принимает массив массивов.Сначала объедините два массива, затем отфильтруйте только уникальные элементы:
редактировать
Как было предложено, более разумным решением будет фильтрация уникальных элементов
b
перед объединением сa
:источник
a
чтобы добавитьb
, то будет ли лучше циклически проходить и использовать push?a.forEach(function(item){ if(a.indexOf(item)<0) a.push(item); });
var c = [...a, ...b.filter(o => !~a.indexOf(o))];
2.var c = [...new Set([...a, ...b])];
☺Это решение ECMAScript 6 с использованием оператора распространения и обобщенные массивы.
В настоящее время он работает только с Firefox и, возможно, с Internet Explorer Technical Preview.
Но если вы используете Вавилон , вы можете получить его сейчас.
источник
Array.from
можно использовать вместо оператора спреда:Array.from(new Set([].concat(...arr)))
ES6
ИЛИ
ИЛИ
источник
union
+ 1-й пример взрывает стек для большихArray
s + 3-й пример невероятно медленен и потребляет много памяти, так какArray
нужно построить две промежуточные s + 3-й пример можно использовать толькоunion
с известными числоArray
s во время компиляции.Set
это путь сюдаИспользуя Set (ECMAScript 2015), это будет так просто:
источник
const array3 = [...new Set(array1.concat(array2))]
Вот немного другой взгляд на петлю. С некоторыми из оптимизаций в последней версии Chrome это самый быстрый метод для разрешения объединения двух массивов (Chrome 38.0.2111).
http://jsperf.com/merge-two-arrays-keeping-only-unique-values
цикл while: ~ 589 тыс. операций / с,
фильтр: ~ 445 тыс. операций / с,
lodash: 308 тыс. операций / с.
петли: 225 тыс. операций / с.
В комментарии указывалось, что одна из моих переменных установки заставляла мой цикл опережать все остальные, потому что не нужно было инициализировать пустой массив для записи. Я согласен с этим, поэтому я переписал тест даже на игровое поле и включил еще более быстрый вариант.
http://jsperf.com/merge-two-arrays-keeping-only-unique-values/52
В этом альтернативном решении я объединил решение ассоциативного массива одного ответа, чтобы устранить
.indexOf()
вызов в цикле, который значительно замедлял работу со вторым циклом, и включил некоторые другие оптимизации, которые другие пользователи также предложили в своих ответах. ,Верхний ответ здесь с двойной петлей для каждого значения (i-1) все еще значительно медленнее. У lodash все еще хорошо, и я бы порекомендовал его всем, кто не против добавить библиотеку в свой проект. Для тех, кто не хочет этого, мой цикл while все еще является хорошим ответом, и ответ фильтра очень ярко демонстрирует здесь, опередив все мои тесты последней версией Canary Chrome (44.0.2360) на момент написания этой статьи.
Проверьте ответ Майка и ответ Dan Стокера , если вы хотите , чтобы шаг на ступеньку выше в скорости. Это, безусловно, самый быстрый из всех результатов после прохождения почти всех жизнеспособных ответов.
источник
Вы можете сделать это просто с ECMAScript 6,
источник
Array.from(new Set(array1.concat(array2)))
.tsconfig.json
, вы можете добавить"downlevelIteration": true
кcompilerOptions
.Гораздо лучшая функция слияния массивов.
источник
var test = ['a', 'b', 'c']; console.log(test);
будет печатать["a", "b", "c", merge: function]
Просто добавляю два моих цента.
Этот метод я часто использую, он использует объект в качестве таблицы hashlookup для проверки дубликатов. Предполагая, что хеш равен O (1), тогда он выполняется в O (n), где n равно a.length + b.length. Честно говоря, я понятия не имею, как браузер выполняет хэширование, но он хорошо работает на многих тысячах точек данных.
источник
String()
функция в javascript. Это может работать для примитивных значений (хотя и с коллизиями между типами), но не подходит для массивов объектов.Просто держитесь подальше от вложенных циклов (O (n ^ 2)) и
.indexOf()
(+ O (n)).источник
Упростил лучший из этого ответа и превратил его в приятную функцию:
источник
Почему вы не используете объект? Похоже, вы пытаетесь смоделировать набор. Однако это не сохранит порядок.
источник
if (!set1.hasOwnProperty(key))
?Лучшее решение ...
Вы можете проверить прямо в консоли браузера, нажав ...
Без дубликата
С дубликатом
Если вы хотите без дубликатов, вы можете попробовать лучшее решение здесь - кричащий код .
Попробуйте на консоли браузера Chrome
Вывод:
источник
Моя полторы копейки
источник
Вы можете добиться этого просто используя Underscore.js's => uniq :
На нем будут напечатаны ["Вижендра", "Сингх", "Шакья"] .
источник
Для ES6 всего одна строка:
источник
Я знаю, что этот вопрос не о массиве объектов, но искатели оказываются здесь.
так что стоит добавить будущим читателям правильный способ объединения и удаления дубликатов ES6
массив объектов :
источник
Реализация
indexOf
метода для других браузеров взята из MDCисточник
from
параметр между прочим?indexOf
. Очистил код, удалив закомментированную часть. @ meder - еще раз спасибо.Новое решение (которое использует
Array.prototype.indexOf
иArray.prototype.concat
):Применение:
Array.prototype.indexOf (для интернет-обозревателя):
источник
Это можно сделать с помощью Set.
источник
Существует так много решений для объединения двух массивов. Их можно разделить на две основные категории (кроме использования сторонних библиотек, таких как lodash или underscore.js).
а) объединить два массива и удалить дублирующиеся элементы.
б) отфильтровать предметы перед их объединением.
Объедините два массива и удалите дублирующиеся элементы
Объединяя
объединительный
Есть много способов объединить массив, я лично предлагаю ниже два метода.
Отфильтруйте элементы перед их объединением
Есть также много способов, но я лично предлагаю приведенный ниже код из-за его простоты.
источник
источник
Хорошая вещь об этом - производительность, и вы вообще, при работе с массивами, используете методы цепочки, такие как filter, map и т. Д., Так что вы можете добавить эту строку, и она будет объединять и дедуплицировать array2 с array1, не обращаясь к последующим ссылкам. один (когда у вас нет методов цепочки), например:
(Я не люблю загрязнять Array.prototype, и это был бы единственный способ уважать цепочку - определение новой функции сломает ее - так что я думаю, что-то вроде этого - единственный способ добиться этого)
источник
Вы можете попробовать это:
источник
Функциональный подход с ES2015
Следуя функциональному подходу a
union
из двухArray
s - это просто композицияconcat
иfilter
. Чтобы обеспечить оптимальную производительность, мы прибегаем к собственномуSet
типу данных, который оптимизирован для поиска свойств.В любом случае, ключевой вопрос в связи с
union
функцией заключается в том, как обрабатывать дубликаты. Возможны следующие перестановки:Первые две перестановки легко обрабатывать с помощью одной функции. Однако последние два являются более сложными, поскольку вы не можете обрабатывать их, пока вы полагаетесь на
Set
поиск. Поскольку переключение на простойObject
поиск старых свойств повлечет за собой серьезное снижение производительности, следующая реализация просто игнорирует третью и четвертую перестановки. Вам придется создать отдельную версию,union
чтобы поддержать их.С этого
unionn
момента становится просто реализовать функцию, которая принимает любое количество массивов (вдохновлено комментариями Наомика):Оказывается,
unionn
это простоfoldl
(акаArray.prototype.reduce
), который принимает вunion
качестве своего редуктора. Примечание. Поскольку в реализации не используется дополнительный аккумулятор, при применении без аргументов будет выдано сообщение об ошибке.источник
flip
иnotf
не используется. ТакжеunionBy
предикат утечки деталей реализации (требует неявного знанияSet
типа). Было бы неплохо, если бы вы могли просто сделать что-то вроде этого:union = unionBy (apply)
иunionci = unionBy (p => x => p(x.toLowerCase()))
. Таким образом, пользователь просто отправляет то, к чему относится значение группировкиp
- просто идея ^ _ ^zs
Объявление переменной также не хватаетvar
/let
ключевое словоради этого ... вот решение одной строки:
Не особо читабельно, но может кому-то помочь:
Set
.Set
массив.sort()
Функция применяется в новый массив.источник
reduce()
тебя можно использоватьArray.from(set)
Дедупликация одного или слияние и дедупликация нескольких входов массива. Пример ниже.
используя ES6 - установить, для, деструктуризации
Я написал эту простую функцию, которая принимает несколько аргументов массива. Практически так же, как и решение, приведенное выше, просто имеет более практический вариант использования. Эта функция не объединяет повторяющиеся значения в одном массиве, поэтому она может удалить их на более позднем этапе.
ОПРЕДЕЛЕНИЕ КРАТКОЙ ФУНКЦИИ (всего 9 строк)
ПРИМЕР ИСПОЛЬЗОВАНИЯ CODEPEN :
источник
arr.map
здесь? Вы используете его как результатforeach
, так как результат игнорируетсяисточник
источник