Jak scalić dwie tablice w JavaScript i de-duplicate items

Mam dwie tablice JavaScript:

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

Chcę, aby wyjście było:

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

Tablica wyjściowa powinna mieć usunięte powtarzające się słowa.

Jak połączyć dwie tablice w JavaScript, aby uzyskać tylko unikalne elementy z każdej tablicy w tej samej kolejności, w jakiej zostały wstawione do oryginalnych tablic?

Author: Peter Mortensen, 2009-10-18

30 answers

Aby po prostu połączyć tablice (bez usuwania duplikatów)

Użycie wersji ES5 Array.concat:

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

var array3 = array1.concat(array2); // Merges both arrays
// [ 'Vijendra', 'Singh', 'Singh', 'Shakya' ]

Użycie wersji ES6 destrukcja

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

Ponieważ nie ma "wbudowanego" sposobu usuwania duplikatów (ECMA-262 faktycznie ma {[7] } co byłoby do tego świetne), musimy to zrobić ręcznie:

Array.prototype.unique = function() {
    var a = this.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
};

Następnie, aby go użyć:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
// Merges both arrays and gets unique items
var array3 = array1.concat(array2).unique(); 

To również zachowa kolejność tablic(tzn. nie wymaga sortowania).

Ponieważ wielu ludzi zirytowane są prototypowe Rozszerzanie pętli Array.prototype i for in, Oto mniej inwazyjny sposób jej użycia:

function arrayUnique(array) {
    var a = array.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
}

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
    // Merges both arrays and gets unique items
var array3 = arrayUnique(array1.concat(array2));

Dla tych, którzy mają szczęście pracować z przeglądarkami, w których ES5 jest dostępny, możesz użyć Object.defineProperty w następujący sposób:

Object.defineProperty(Array.prototype, 'unique', {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function() {
        var a = this.concat();
        for(var i=0; i<a.length; ++i) {
            for(var j=i+1; j<a.length; ++j) {
                if(a[i] === a[j])
                    a.splice(j--, 1);
            }
        }

        return a;
    }
});
 1279
Author: LiraNuna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 16:45:30

Z Podkreśleniem.js lub Lo-Dash można zrobić:

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

Http://underscorejs.org/#union

Http://lodash.com/docs#union

 515
Author: GijsjanB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:32:13

Najpierw połącz dwie tablice, następnie odfiltruj tylko unikalne elementy.

var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b);
var d = c.filter(function (item, pos) {return c.indexOf(item) == pos});

// d is [1,2,3,101,10]

Http://jsfiddle.net/simo/98622/

Edit

Zgodnie z sugestią @Dmitry (zobacz drugi komentarz poniżej) bardziej wydajnym rozwiązaniem byłoby odfiltrowanie unikalnych elementów w b przed połączeniem z a

var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b.filter(function (item) {
    return a.indexOf(item) < 0;
}));

// d is [1,2,3,101,10]
 204
Author: simo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 22:25:45

Jest to rozwiązanie ECMAScript 6 wykorzystujące operator spreadu i array generics.

Obecnie działa tylko z Firefoksem i ewentualnie Internet Explorer Technical Preview.

Ale jeśli użyjesz Babel , możesz go mieć teraz.

// Input: [ [1, 2, 3], [101, 2, 1, 10], [2, 1] ]
// Output: [1, 2, 3, 101, 10]
function mergeDedupe(arr)
{
  return [...new Set([].concat(...arr))];
}
 123
Author: Adria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:39:25

ES6

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

Lub

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

Lub

[...new Set([...array1 ,...array2])]; //   => remove duplication
 98
Author: Abdennour TOUMI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-17 03:21:51

Oto nieco inne spojrzenie na pętlę. Dzięki niektórym optymalizacjom w najnowszej wersji Chrome jest to najszybsza metoda rozwiązywania połączenia dwóch tablic (Chrome 38.0.2111).

Http://jsperf.com/merge-two-arrays-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 loop: ~ 589k / s
filtr: ~445km / s
lodash: 308k ops / s
dla pętli: 225k/s

Komentarz wskazywał, że jedna z moich zmiennych konfiguracyjnych powodowała, że moja pętla przeciągnij przed resztą, ponieważ nie musiał inicjalizować pustej tablicy do zapisu. Zgadzam się z tym, więc przepisałem test na równi z polem gry i włączyłem jeszcze szybszą opcję.

Http://jsperf.com/merge-two-arrays-keeping-only-unique-values/21

var whileLoopAlt = function(array1, array2) {
    var array3 = [];
    var arr = array1.concat(array2);
    var len = arr.length;
    var assoc = {};

    while(len--) {
        var itm = arr[len];

        if(!assoc[itm]) { // Eliminate the indexOf call
            array3.unshift(itm);
            assoc[itm] = true;
        }
    }

    return array3;
};

W tym alternatywnym rozwiązaniu połączyłem asocjacyjne rozwiązanie tablicy jednej odpowiedzi, aby wyeliminować wywołanie .indexOf() W pętli, które spowalniało wiele rzeczy za pomocą drugiej pętli, i włączyłem kilka innych optymalizacji, które inni użytkownicy zasugerowali również w swoich odpowiedziach.

Górna odpowiedź z podwójną pętlą na każdej wartości (i-1) jest nadal znacznie wolniejsza. lodash wciąż robi silne wrażenie i nadal polecam go każdemu, kto nie ma nic przeciwko dodaniu biblioteki do swojego projektu. Dla tych, którzy nie chcą, moja pętla while jest nadal dobrą odpowiedzią, a odpowiedź filtra ma bardzo silny pokaz tutaj, pokonując wszystkie moje testy z najnowszym Canary Chrome (44.0.2360)

Sprawdź odpowiedź Mike ' a i Dana Stockera, jeśli chcesz przyspieszyć. Są to zdecydowanie najszybsze ze wszystkich wyników po przejściu przez prawie wszystkie realne odpowiedzi.
 31
Author: slickplaid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:36:46

Używając Zestawu (ECMAScript 2015), będzie to tak proste:

const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = Array.from(new Set(array1.concat(array2)));
 29
Author: Benny Neugebauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-06 19:05:58

Możesz to zrobić po prostu za pomocą ECMAScript 6,

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
  • Użyj operatora spreadu do łączenia tablicy.
  • użyj zestawu do utworzenia odrębnego zestawu elementów.
  • ponownie użyj operatora spread, aby przekonwertować Zbiór na tablicę.
 28
Author: Rajaprabhu Aravindasamy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:50:33
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;
};

Znacznie lepszą funkcję scalania tablic.

 14
Author: GAgnew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-22 18:44:21

Dorzucę tylko dwa centy.

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;
}

Jest to metoda, której często używam, używa obiektu jako tabeli hashlookup do sprawdzania duplikatów. Zakładając, że hash jest O (1), to działa w O (N), gdzie n jest a. length + b. length. Szczerze mówiąc, nie mam pojęcia, jak przeglądarka robi hash, ale działa dobrze na wielu tysiącach punktów danych.

 14
Author: Mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-12 19:50:20

Dlaczego nie używasz obiektu? Wygląda na to, że próbujesz wymodelować zestaw. To jednak nie zachowa porządku.

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
}
 13
Author: Nick Retallack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:30:39

Unikaj zagnieżdżonych pętli(O (N^2)) i .indexOf() (+O (n)).

function merge(a, b) {
    var hash = {}, i;
    for (i=0; i<a.length; i++) {
        hash[a[i]]=true;
    } 
    for (i=0; i<b.length; i++) {
        hash[b[i]]=true;
    } 
    return Object.keys(hash);
}
 11
Author: Dan Stocker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-20 14:55:47

Mój półtora grosza:

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);
 8
Author: Hero Qu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-20 22:29:23

Uprościłem odpowiedź simo i przekształciłem ją w ładną funkcję.

function mergeUnique(arr1, arr2){
    return arr1.concat(arr2.filter(function (item) {
        return arr1.indexOf(item) === -1;
    }));
}
 8
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-09 12:30:27

Najlepsze rozwiązanie...

Możesz sprawdzić bezpośrednio w konsoli przeglądarki, naciskając...

Bez duplikatu

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

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

Z duplikatem

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

Jeśli chcesz bez duplikatu możesz spróbować lepszego rozwiązania stąd - krzycząc kod.

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

Spróbuj na konsoli przeglądarki Chrome

 f12 > console

Wyjście:

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

[1, 2, 3, "prince"]
 7
Author: Zigri2612,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:49:08
//Array.indexOf was introduced in javascript 1.6 (ECMA-262) 
//We need to implement it explicitly for other browsers, 
if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt, from)
  {
    var len = this.length >>> 0;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}
//now, on to the problem

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

var merged = array1.concat(array2);
var t;
for(i = 0; i < merged.length; i++)
  if((t = merged.indexOf(i + 1, merged[i])) != -1)
  {
    merged.splice(t, 1);
    i--;//in case of multiple occurrences
  }

Implementacja metody indexOf dla innych przeglądarek pochodzi z MDC

 6
Author: Amarghosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-18 10:56:09

Można to zrobić za pomocą Set.

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

var array3 = array1.concat(array2);
var tempSet = new Set(array3);
array3 = Array.from(tempSet);

//show output
document.body.querySelector("div").innerHTML = JSON.stringify(array3);
<div style="width:100%;height:4rem;line-height:4rem;background-color:steelblue;color:#DDD;text-align:center;font-family:Calibri" > 
  temp text 
</div>
 6
Author: Karan Singla,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 10:02:09
Array.prototype.add = function(b){
    var a = this.concat();                // clone current object
    if(!b.push || !b.length) return a;    // if b is not an array, or empty, then return a unchanged
    if(!a.length) return b.concat();      // if original is empty, return b

    // go through all the elements of b
    for(var i = 0; i < b.length; i++){
        // if b's value is not in a, then add it
        if(a.indexOf(b[i]) == -1) a.push(b[i]);
    }
    return a;
}

// Example:
console.log([1,2,3].add([3, 4, 5])); // will output [1, 2, 3, 4, 5]
 5
Author: Lajos Meszaros,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 11:38:21

Możesz to osiągnąć po prostu używając podkreślenia.js = > uniq :

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

console.log(array3)

Wydrukuje ["Vijendra", "Singh","Shakya"] .

 5
Author: Mohideen ibn Mohammed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 06:54:55
array1.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)

Fajną rzeczą w tym jest wydajność i to, że w ogóle, podczas pracy z tablicami, są metody łańcuchowe, takie jak filtr, Mapa, itp., więc możesz dodać tę linię I będzie ona łączyć i deduplikować array2 z array1 bez konieczności odniesienia do późniejszego (gdy masz metody łańcuchowe, których nie masz), przykład:

someSource()
.reduce(...)
.filter(...)
.map(...) 
// and now you want to concat array2 and deduplicate:
.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)
// and keep chaining stuff
.map(...)
.find(...)
// etc

(nie lubię zanieczyszczać tablicy.prototyp i to byłby jedyny sposób respektowania łańcucha-zdefiniowanie nowej funkcji go złamie-więc myślę, że coś takiego jest jedynym sposobem na osiągnięcie tego)

 5
Author: cancerbero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 10:10:01

Nowe rozwiązanie (które wykorzystuje Array.prototype.indexOf i Array.prototype.concat ):

Array.prototype.uniqueMerge = function( a ) {
    for ( var nonDuplicates = [], i = 0, l = a.length; i<l; ++i ) {
        if ( this.indexOf( a[i] ) === -1 ) {
            nonDuplicates.push( a[i] );
        }
    }
    return this.concat( nonDuplicates )
};

Użycie:

>>> ['Vijendra', 'Singh'].uniqueMerge(['Singh', 'Shakya'])
["Vijendra", "Singh", "Shakya"]

Array.prototyp.indexOf (dla internet Explorera):

Array.prototype.indexOf = Array.prototype.indexOf || function(elt)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from): Math.floor(from); 
    if (from < 0)from += len;

    for (; from < len; from++)
    {
      if (from in this && this[from] === elt)return from;
    }
    return -1;
  };
 4
Author: meder omuraliev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-18 11:10:45

W Dojo 1.6 +

var unique = []; 
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2); // Merged both arrays

dojo.forEach(array3, function(item) {
    if (dojo.indexOf(unique, item) > -1) return;
    unique.push(item); 
});

Update

Zobacz kod roboczy.

Http://jsfiddle.net/UAxJa/1/

 2
Author: Richard Ayotte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-12 13:30:21

Połącz nieograniczoną liczbę tablic lub innych tablic i zachowaj unikalność:

function flatMerge() {
    return Array.prototype.reduce.call(arguments, function (result, current) {
        if (!(current instanceof Array)) {
            if (result.indexOf(current) === -1) {
                result.push(current);
            }
        } else {
            current.forEach(function (value) {
                console.log(value);
                if (result.indexOf(value) === -1) {
                    result.push(value);
                }
            });
        }
        return result;
    }, []);
}

flatMerge([1,2,3], 4, 4, [3, 2, 1, 5], [7, 6, 8, 9], 5, [4], 2, [3, 2, 5]);
// [1, 2, 3, 4, 5, 7, 6, 8, 9]

flatMerge([1,2,3], [3, 2, 1, 5], [7, 6, 8, 9]);
// [1, 2, 3, 5, 7, 6, 8, 9]

flatMerge(1, 3, 5, 7);
// [1, 3, 5, 7]
 2
Author: TxRegex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 18:02:29

Zakładając, że oryginalne tablice nie wymagają deduplikacji, powinno to być dość szybkie, zachować pierwotną kolejność i nie modyfikować oryginalnych tablic...

function arrayMerge(base, addendum){
    var out = [].concat(base);
    for(var i=0,len=addendum.length;i<len;i++){
        if(base.indexOf(addendum[i])<0){
            out.push(addendum[i]);
        }
    }
    return out;
}

Użycie:

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

console.log(array3);
//-> [ 'Vijendra', 'Singh', 'Shakya' ]
 2
Author: Billy Moon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 23:27:58

Podejście funkcjonalne z ES2015

Zgodnie z podejściem funkcjonalnym a union z dwóch ArrayS jest tylko składem concat i filter. W celu zapewnienia optymalnej wydajności korzystamy z natywnego typu danych Set, który jest zoptymalizowany pod kątem wyszukiwania właściwości.

W każdym razie, kluczowym pytaniem w połączeniu z funkcją union jest sposób traktowania duplikatów. Możliwe są następujące permutacje:

Array A      + Array B

[unique]     + [unique]
[duplicated] + [unique]
[unique]     + [duplicated]
[duplicated] + [duplicated]

Pierwsze dwie permutacje są łatwe w obsłudze za pomocą pojedyncza funkcja. Jednak dwa ostatnie są bardziej skomplikowane, ponieważ nie można ich przetwarzać tak długo, jak długo można polegać na wyszukiwaniach Set. Ponieważ przejście na zwykłą starą właściwość Object oznaczałoby poważny hit wydajności, następująca implementacja ignoruje trzecią i czwartą permutację. Trzeba by zbudować osobną wersję union, aby je obsługiwać.


// small, reusable auxiliary functions

const comp = f => g => x => f(g(x));
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// de-duplication

const dedupe = comp(afrom) (createSet);


// the actual union function

const union = xs => ys => {
  const zs = createSet(xs);  
  return concat(xs) (
    filter(x => zs.has(x)
     ? false
     : zs.add(x)
  ) (ys));
}


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];


// here we go

console.log( "unique/unique", union(dedupe(xs)) (ys) );
console.log( "duplicated/unique", union(xs) (ys) );

Od tego momentu staje się trywialne zaimplementowanie unionn funkcji, która przyjmuje dowolne liczba tablic (zainspirowana komentarzami naomika):

// small, reusable auxiliary functions

const uncurry = f => (a, b) => f(a) (b);
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);

const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// union and unionn

const union = xs => ys => {
  const zs = createSet(xs);  
  return concat(xs) (
    filter(x => zs.has(x)
     ? false
     : zs.add(x)
  ) (ys));
}

const unionn = (head, ...tail) => foldl(union) (head) (tail);


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];
const zs = [0,1,2,3,4,5,6,7,8,9];


// here we go

console.log( unionn(xs, ys, zs) );

Okazuje się, że unionn jest po prostu foldl (aka Array.prototype.reduce), która przyjmuje union jako swój reduktor. Uwaga: Ponieważ implementacja nie używa dodatkowego akumulatora, spowoduje błąd, gdy zastosujesz go bez argumentów.

 2
Author: ftor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-11 08:08:28

Najprostszym sposobem na to jest użycie concat() do scalania tablic, a następnie użycie filter() do usuwania duplikatów, lub użycie concat(), a następnie umieszczenie Scalonej tablicy wewnątrz Set().

Pierwsza droga:

const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
//now use filter to remove dups
const removeDuplicates = mergedArray.filter((elem, index) =>  mergedArray.indexOf(elem) === index); // [1,2,3, 4]

Drugi sposób (ale z wpływami wydajności na interfejs użytkownika):

const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
const removeDuplicates = new Set(mergedArray);
 2
Author: Stelios Voskos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-10 20:11:37

Wygląda na to, że zaakceptowana odpowiedź jest najwolniejsza w moich testach;

Uwaga scalam 2 tablice obiektów za pomocą klucza

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<button type='button' onclick='doit()'>do it</button>
<script>
function doit(){
    var items = [];
    var items2 = [];
    var itemskeys = {};
    for(var i = 0; i < 10000; i++){
        items.push({K:i, C:"123"});
        itemskeys[i] = i;
    }

    for(var i = 9000; i < 11000; i++){
        items2.push({K:i, C:"123"});
    }

    console.time('merge');
    var res = items.slice(0);

    //method1();
    method0();
    //method2();

    console.log(res.length);
    console.timeEnd('merge');

    function method0(){
        for(var i = 0; i < items2.length; i++){
            var isok = 1;
            var k = items2[i].K;
            if(itemskeys[k] == null){
                itemskeys[i] = res.length;
                res.push(items2[i]);
            }
        }
    }

    function method1(){
        for(var i = 0; i < items2.length; i++){
            var isok = 1;
            var k = items2[i].K;

            for(var j = 0; j < items.length; j++){
                if(items[j].K == k){
                    isok = 0;
                    break;
                }
            }

            if(isok) res.push(items2[i]);
        }  
    }

    function method2(){
        res = res.concat(items2);
        for(var i = 0; i < res.length; ++i) {
            for(var j = i+1; j < res.length; ++j) {
                if(res[i].K === res[j].K)
                    res.splice(j--, 1);
            }
        }
    }
}
</script>
</body>
</html>
 2
Author: Omu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 12:17:41

Dla dobra tego... oto rozwiązanie pojedynczej linii:

const x = [...new Set([['C', 'B'],['B', 'A']].reduce( (a, e) => a.concat(e), []))].sort()
// ['A', 'B', 'C']

Niezbyt czytelny, ale może komuś pomóc:

  1. stosuje funkcję reduce z początkową wartością akumulatora ustawioną na pustą tablicę.
  2. funkcja reduce używa concat do dołączania każdej tablicy podrzędnej do tablicy akumulatorów.
  3. wynik jest przekazywany jako parametr konstruktora do utworzenia nowego Set.
  4. operator spreadu jest używany do Konwersji Set na / align = "left" /
  5. Funkcja sort() zostanie zastosowana do nowej tablicy.
 2
Author: Mark Tyers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-03 21:48:29

Deduplikacja pojedynczych lub scalonych i deduplikacja wielu wejść tablicy. Przykład poniżej.

Useing ES6-Set, for of, destructuring

Napisałem prostą funkcję, która pobiera wiele argumentów tablicy. Czy prawie tak samo jak powyżej rozwiązanie ma tylko bardziej praktyczny przypadek użycia. Ta funkcja nie łączy zduplikowanych wartości tylko do jednej tablicy tak, że może je usunąć na późniejszym etapie.

Krótka definicja funkcji (tylko 9 linii )

/**
* This function merging only arrays unique values. It does not merges arrays in to array with duplicate values at any stage.
*
* @params ...args Function accept multiple array input (merges them to single array with no duplicates)
* it also can be used to filter duplicates in single array
*/
function arrayDeDuplicate(...args){
   let set = new Set(); // init Set object (available as of ES6)
   for(let arr of args){ // for of loops through values
      arr.map((value) => { // map adds each value to Set object
         set.add(value); // set.add method adds only unique values
      });
   }
   return [...set]; // destructuring set object back to array object
   // alternativly we culd use:  return Array.from(set);
}

UŻYJ PRZYKŁADU CODEPEN :

// SCENARIO 
let a = [1,2,3,4,5,6];
let b = [4,5,6,7,8,9,10,10,10];
let c = [43,23,1,2,3];
let d = ['a','b','c','d'];
let e = ['b','c','d','e'];

// USEAGE
let uniqueArrayAll = arrayDeDuplicate(a, b, c, d, e);
let uniqueArraySingle = arrayDeDuplicate(b);

// OUTPUT
console.log(uniqueArrayAll); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 43, 23, "a", "b", "c", "d", "e"]
console.log(uniqueArraySingle); // [4, 5, 6, 7, 8, 9, 10]
 2
Author: DevWL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 03:10:28

Połącz dwie tablice i usuń duplikaty w 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 ]
 2
Author: Yin Gong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-03 04:09:04