Как объединить два массива в JavaScript и удалить дубликаты

У меня есть два массива JavaScript:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

Я хочу, чтобы вывод был:

var array3 = ["Vijendra","Singh","Shakya"];

Выходной массив должен удалить повторные слова.

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

Решение

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

Версия ES5 использует Array.concat:

& Лт;!- начать фрагмент: js hide: ложная консоль: истинная павиана: false - >

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];

console.log(array1.concat(array2));

& Лт;!- конец фрагмента - >

ES6 версия использует [деструктурирование][2]

const array1 = ["Vijendra","Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = [...array1, ...array2];

Поскольку нет «встроенного» способа удаления дубликатов ([ECMA-262][1] на самом деле имеет «Array.forEach», что было бы здорово для этого), мы должны сделать это вручную:


Array.prototype.unique = function() {
    var a = this.concat();
    for(var i=0; i
Комментарии (16)

С Underscore.js или Lo-Dash вы можете сделать:

& Лт;!- начать фрагмент: js hide: ложная консоль: истинная павиана: false - >

console.log(_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]));

& Лт;!- язык: lang-html - >

< script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"> < / script >

& Лт;!- конец фрагмента - >

Http://underscorejs.org/#union

http://lodash.com/docs#union

Комментарии (11)

Сначала объедините два массива, затем отфильтруйте только уникальные элементы:

& Лт;!- начать фрагмент: js hide: ложная консоль: истинная павиана: false - >

var a = [1, 2, 3], b = [101, 2, 1, 10]
var c = a.concat(b)
var d = c.filter((item, pos) => c.indexOf(item) === pos)

console.log(d) // d is [1, 2, 3, 101, 10]

& Лт;!- конец фрагмента - >

Редактировать

Как было предложено, более разумным решением было бы отфильтровать уникальные элементы в b перед объединением с a:

& Лт;!- начать фрагмент: js hide: ложная консоль: истинная павиана: false - >

var a = [1, 2, 3], b = [101, 2, 1, 10]
var c = a.concat(b.filter((item) => a.indexOf(item) < 0))

console.log(c) // c is [1, 2, 3, 101, 10]

& Лт;!- конец фрагмента - >

Комментарии (7)

Это решение ECMAScript & nbsp; 6 с использованием [оператора спред][1] и дженериков массива.

В настоящее время он работает только с Firefox и, возможно, с Internet & nbsp; Explorer Technical Preview.

Но если вы используете Babel, вы можете получить его сейчас.

// Input: [ [1, 2, 3], [101, 2, 1, 10], [2, 1] ]
// Output: [1, 2, 3, 101, 10]
function mergeDedupe(arr)
{
  return [...new Set([].concat(...arr))];
}

[1]: http://kangax.github.io/compat-table/es6/#spread_%28...% 29_operator

Комментарии (14)

ES6

array1.push(...array2) // => don't remove duplication 

ИЛИ

[...array1,...array2] //   =>  don't remove duplication 

ИЛИ

[...new Set([...array1 ,...array2])]; //   => remove duplication
Комментарии (7)

С помощью установка (в ECMAScript 2015), это будет так просто:

const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = Array.from(new Set(array1.concat(array2)));
Комментарии (3)

Вот немного другой взгляд на петлю. С некоторыми оптимизациями в последней версии Chrome, это самый быстрый метод для разрешения объединения двух массивов (Chrome 38.0.2111).

http://jsperf.com/merge-two-rrays-keeping-only-unique-values

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [];

var arr = array1.concat(array2),
  len = arr.length;

while (len--) {
  var itm = arr[len];
  if (array3.indexOf(itm) === -1) {
    array3.unshift(itm);
  }
}

цикл while: ~ 589k ops / s < br / > фильтр: ~ 445k операций / с < br / > lodash: 308k операций / с < br / > для петель: 225 КБ опс / с

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

http://jsperf.com/merge-two-rrays-keeping-only-unique-values/52

let whileLoopAlt = function (array1, array2) {
    const array3 = array1.slice(0);
    let len1 = array1.length;
    let len2 = array2.length;
    const assoc = {};

    while (len1--) {
        assoc[array1[len1]] = null;
    }

    while (len2--) {
        let itm = array2[len2];

        if (assoc[itm] === undefined) { // Eliminate the indexOf call
            array3.push(itm);
            assoc[itm] = null;
        }
    }

    return array3;
};

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

Верхний ответ здесь с двойным циклом на каждом значении (i-1) все еще значительно медленнее. Лодаш все еще сильна, и я все равно рекомендую его всем, кто не против добавить библиотеку в свой проект. Для тех, кто не хочет, мой цикл while по-прежнему является хорошим ответом, и ответ фильтра имеет очень сильный показ здесь, выбивая все мои тесты с последним Canary Chrome (44.0.2360) на момент написания этой статьи.

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

Комментарии (10)

Вы можете сделать это просто с ECMAScript & nbsp; 6,

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
  • Используйте оператор спред для объединения массива.
  • Используйте Set для создания отдельного набора элементов.
  • Снова используйте оператор спреда, чтобы преобразовать Набор в массив.
Комментарии (3)

Решение, основанное на ES6 Союза

в

let arr1 = [1,2,3,4,5];
let arr2 = [3,4,5,6];
let result = [...new Set([...arr1, ...arr2])];
console.log(result);

в

Комментарии (1)

объединить два массива и удалить дубликат в es6

let arr1 = [3, 5, 2, 2, 5, 5];
let arr2 = [2, 1, 66, 5];
let unique = [...new Set([...arr1,...arr2])];
console.log(unique);
// [ 3, 5, 2, 1, 66 ]
Комментарии (0)

Просто держитесь подальше от вложенных циклов (O (n ^ 2)) и .indexOf () (+ O (n)).


function merge(a, b) {
    var hash = {}, i;
    for (i=0; i
Комментарии (1)
Array.prototype.merge = function(/* variable number of arrays */){
    for(var i = 0; i < arguments.length; i++){
        var array = arguments[i];
        for(var j = 0; j < array.length; j++){
            if(this.indexOf(array[j]) === -1) {
                this.push(array[j]);
            }
        }
    }
    return this;
};

Гораздо лучшая функция слияния массива.

Комментарии (6)

Просто бросаю мои два цента.

function mergeStringArrays(a, b){
    var hash = {};
    var ret = [];

    for(var i=0; i < a.length; i++){
        var e = a[i];
        if (!hash[e]){
            hash[e] = true;
            ret.push(e);
        }
    }

    for(var i=0; i < b.length; i++){
        var e = b[i];
        if (!hash[e]){
            hash[e] = true;
            ret.push(e);
        }
    }

    return ret;
}

Этот метод я часто использую, он использует объект в качестве таблицы хеш-смотров для проверки дубликатов. Предполагая, что хеш - O (1), он запускается в O (n), где n - a.length + b.length. Я, честно говоря, понятия не имею, как браузер выполняет хеш, но он хорошо работает на многих тысячах точек данных.

Комментарии (3)

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

var set1 = {"Vijendra":true, "Singh":true}
var set2 = {"Singh":true,  "Shakya":true}

// Merge second object into first
function merge(set1, set2){
  for (var key in set2){
    if (set2.hasOwnProperty(key))
      set1[key] = set2[key]
  }
  return set1
}

merge(set1, set2)

// Create set from array
function setify(array){
  var result = {}
  for (var item in array){
    if (array.hasOwnProperty(item))
      result[array[item]] = true
  }
  return result
}
Комментарии (2)
  • современный способ добиться этого-просто использовать распространение оператора.
  • И, чтобы избежать дублирования, мы можем эффективно использовать наборы; наборы выиграл'т разрешить дубликаты по умолчанию.
  • Для получения выходных данных в виде массива из набора, можно использовать массив.из()

Итак, здесь'с демонстрацией для вашего сценария

в

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var resArr = Array.from(new Set([...array1, ...array2]));
console.log(resArr);

в

Комментарии (0)

Лучшее решение...

Вы можете проверить прямо в консоли браузера, нажав...

Без дубликата

a = [1, 2, 3];
b = [3, 2, 1, "prince"];

a.concat(b.filter(function(el) {
    return a.indexOf(el) === -1;
}));

С дубликатом

["prince", "asish", 5].concat(["ravi", 4])

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

[1, 2, 3].concat([3, 2, 1, "prince"].filter(function(el) {
    return [1, 2, 3].indexOf(el) === -1;
}));

Попробуйте на консоли браузера Chrome

 f12 > console

Вывод:

["prince", "asish", 5, "ravi", 4]

[1, 2, 3, "prince"]
Комментарии (3)

Упрощен ответ Симо и превратил его в хорошую функцию.

function mergeUnique(arr1, arr2){
    return arr1.concat(arr2.filter(function (item) {
        return arr1.indexOf(item) === -1;
    }));
}
Комментарии (1)

Мои полтора копейки:

Array.prototype.concat_n_dedupe = function(other_array) {
  return this
    .concat(other_array) // add second
    .reduce(function(uniques, item) { // dedupe all
      if (uniques.indexOf(item) == -1) {
        uniques.push(item);
      }
      return uniques;
    }, []);
};

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var result = array1.concat_n_dedupe(array2);

console.log(result);
Комментарии (2)

Вы можете достичь этого просто, используя Underscore.js's = > uniq :

array3 = _.uniq(array1.concat(array2))

console.log(array3)

Он напечатает ["Виджендра", "Сингх", "Шакья"] .

Комментарии (0)

Новое решение (в котором используются Array.prototype.indexOf и Array.prototype.concat):


Array.prototype.uniqueMerge = function( a ) {
    for ( var nonDuplicates = [], i = 0, l = a.length; i
Комментарии (16)