web-dev-qa-db-fra.com

Comment fusionner deux tableaux en JavaScript et supprimer des éléments en double

J'ai deux tableaux JavaScript:

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

Je veux que la sortie soit:

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

Le tableau de sortie doit avoir les mots répétés supprimés.

Comment fusionner deux tableaux en JavaScript afin de n'obtenir que les éléments uniques de chaque tableau dans le même ordre dans lequel ils ont été insérés dans les tableaux d'origine?

1090
Vijjendra

Pour simplement fusionner les tableaux (sans supprimer les doublons)

Version ES5, utilisez Array.concat:

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

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

Version ES6 utilisation déstructuration

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

Comme il n’existe pas de méthode «intégrée» pour supprimer les doublons ( ECMA-262 a en fait Array.forEach, ce qui serait bien pour cela), nous devons le faire manuellement:

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

Ensuite, pour l'utiliser:

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

Cela préservera également l’ordre des tableaux (c’est-à-dire qu’aucun tri n’est nécessaire).

Étant donné que beaucoup de gens sont agacés par l'augmentation du prototype des boucles Array.prototype et for in, voici une façon moins invasive de l'utiliser:

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

Pour ceux qui ont la chance de travailler avec des navigateurs sur lesquels ES5 est disponible, vous pouvez utiliser Object.defineProperty comme ceci:

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;
    }
});
1370
LiraNuna

Avec Underscore.js ou Lo-Dash, vous pouvez effectuer les tâches suivantes:

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

http://underscorejs.org/#union

http://lodash.com/docs#union

533
GijsjanB

Commencez par concaténer les deux tableaux, puis filtrez uniquement les éléments uniques.

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/

Modifier

Comme suggéré par @Dmitry (voir le deuxième commentaire ci-dessous), une solution plus judicieuse en termes de performances serait de filtrer les éléments uniques dans b avant de les concaténer avec 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]
220
simo

Il s’agit d’une solution ECMAScript 6 utilisant propagation des génériques d’opérateur et de tableau.

Actuellement, cela ne fonctionne qu'avec Firefox, et éventuellement avec Internet Explorer Technical Preview.

Mais si vous utilisez Babel , vous pouvez l’avoir maintenant.

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

ES6

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

OR

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

OR

[...new Set([...array1 ,...array2])]; //   => remove duplication
113
Abdennour TOUMI

Avec un Set (ECMAScript 2015), ce sera aussi simple que cela:

const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = Array.from(new Set(array1.concat(array2)));
46
Benny Neugebauer

Voici une version légèrement différente de la boucle. Avec certaines des optimisations de la dernière version de Chrome, il s'agit de la méthode la plus rapide pour résoudre l'union des deux tableaux (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);
  }
}

boucle While: ~ 589k ops/s 
filtre: ~ 445k ops/s 
lodash: 308k ops/s 
pour les boucles: 225k op/s

Un commentaire a souligné que l'une de mes variables de configuration faisait que ma boucle devançait les autres, car elle n'avait pas besoin d'initialiser un tableau vide pour écrire. Je suis d’accord avec ça, j’ai donc réécrit le test sur un pied d’égalité et ajouté une option encore plus rapide.

http://jsperf.com/merge-two-arrays-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;
};

Dans cette solution alternative, j'ai combiné la solution de tableau associatif d'une réponse pour éliminer l'appel .indexOf() de la boucle, ce qui ralentissait considérablement les choses avec une seconde boucle, et incluait certaines des autres optimisations suggérées par d'autres utilisateurs dans leurs réponses. bien.

La réponse principale ici avec la double boucle sur chaque valeur (i-1) est toujours beaucoup plus lente. lodash continue à bien se porter, et je le recommanderais quand même à quiconque ne verrait pas d'inconvénient à ajouter une bibliothèque à son projet. Pour ceux qui ne veulent pas, ma boucle while est toujours une bonne réponse et la réponse du filtre a une très bonne impression ici, battant tous mes tests avec la dernière version de Canary Chrome (44.0.2360) au moment de la rédaction de cet article.

Consultez la réponse de Mike et la réponse de Dan Stocker si vous voulez augmenter la vitesse. Ce sont de loin les résultats les plus rapides après avoir passé en revue toutes les réponses viables.

33
slickplaid

Vous pouvez le faire simplement avec ECMAScript 6,

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
  • Utilisez l'opérateur spread pour concaténer le tableau.
  • Utilisez Set pour créer un ensemble distinct d’éléments.
  • Utilisez à nouveau l'opérateur spread pour convertir l'ensemble en un tableau.
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;
};

Une fonction de fusion de tableau bien meilleure. 

16
GAgnew

fusionner deux tableaux et supprimer les doublons dans 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 ]
15
Yin Gong

Il suffit simplement d'éviter les boucles imbriquées (O (n ^ 2)) et .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);
}
14
Dan Stocker

Je viens de jeter mes deux sous.

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

C’est une méthode que j’utilise beaucoup, elle utilise un objet comme table hashlookup pour effectuer la vérification des doublons. En supposant que le hachage est O (1), cela se passe dans O(n) où n est a.length + b.length. Honnêtement, je ne sais pas du tout comment le navigateur effectue le hachage, mais il fonctionne bien sur plusieurs milliers de points de données.

14
Mike

Pourquoi n'utilisez-vous pas un objet? On dirait que vous essayez de modéliser un ensemble. Cela ne préservera pas l'ordre, cependant.

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
Nick Retallack

Mon centime et demi:

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
Hero Qu

La meilleure solution...

Vous pouvez vérifier directement dans la console du navigateur en appuyant sur ...

Sans doublon

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

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

Avec duplicata

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

Si vous voulez sans doublon, vous pouvez essayer une meilleure solution à partir d'ici - Shouting Code .

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

Essayez sur la console du navigateur Chrome

 f12 > console

Sortie:

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

[1, 2, 3, "prince"]
8
Zigri2612

Simplifié la réponse de simo et l'a transformée en une fonction de Nice.

function mergeUnique(arr1, arr2){
    return arr1.concat(arr2.filter(function (item) {
        return arr1.indexOf(item) === -1;
    }));
}
8
Andrew

Vous pouvez y arriver simplement en utilisant Underscore.js => uniq :

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

console.log(array3)

Il affichera ["Vijendra", "Singh", "Shakya"] .

6
//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
  }

L'implémentation de la méthode indexOf pour d'autres navigateurs provient de MDC

6
Amarghosh

Cela peut être fait en utilisant 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
Karan Singla
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
Lajos Meszaros
array1.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)

La bonne chose à propos de celui-ci est la performance et qu'en général, lorsque vous travaillez avec des tableaux, vous enchaînez des méthodes telles que filter, map, etc., de sorte que vous puissiez ajouter cette ligne pour concaténer et dédupliquer array2 avec array1 sans qu'il soit nécessaire de faire référence à ce dernier. un (lorsque vous chaînez des méthodes que vous n'avez pas), exemple: 

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

(Je n'aime pas polluer Array.prototype et ce serait la seule façon de respecter la chaîne - la définition d'une nouvelle fonction la casserait - donc je pense qu'une telle chose est la seule façon d'accomplir cela)

5
cancerbero

Nouvelle solution (qui utilise Array.prototype.indexOf et 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 )
};

Usage:

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

Array.prototype.indexOf (pour Internet Explorer):

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;
  };
5
meder omuraliev

Pour ES6, une seule ligne:

a = [1, 2, 3, 4]
b = [4, 5]
[...new Set(a.concat(b))]  // [1, 2, 3, 4, 5]
4
user1079877
var arr1 = [1, 3, 5, 6];
var arr2 = [3, 6, 10, 11, 12];
arr1.concat(arr2.filter(ele => !arr1.includes(ele)));
console.log(arr1);

output :- [1, 3, 5, 6, 10, 11, 12]
3
Bharti Ladumor

pour le plaisir ... voici une solution en une seule ligne:

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

Pas particulièrement lisible mais cela peut aider quelqu'un:

  1. Applique une fonction de réduction avec la valeur d'accumulateur initiale définie à un tableau vide.
  2. La fonction de réduction utilise concat pour ajouter chaque sous-tableau au tableau d'accumulateur.
  3. Le résultat est passé en tant que paramètre constructeur pour créer une nouvelle variable Set.
  4. L'opérateur spread est utilisé pour convertir la Set en un tableau.
  5. La fonction sort() est appliquée au nouveau tableau.
3
Mark Tyers

Une approche fonctionnelle avec ES2015

En suivant l’approche fonctionnelle, un union de deux Arrays n’est que la composition de concat et filter. Afin de fournir des performances optimales, nous avons recours au type de données natif Set, optimisé pour les recherches de propriété.

Quoi qu'il en soit, la question clé associée à une fonction union est de savoir comment traiter les doublons. Les permutations suivantes sont possibles:

Array A      + Array B

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

Les deux premières permutations sont faciles à manipuler avec une seule fonction. Cependant, les deux derniers sont plus compliqués, car vous ne pouvez pas les traiter tant que vous vous fiez à des recherches Set. Étant donné que le passage à des recherches de propriétés Object plaines et anciennes entraînerait des conséquences sérieuses, l’implémentation suivante ignore la troisième et la quatrième permutation. Vous devrez créer une version distincte de union pour les prendre en charge.


// 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) );

À partir de là, il devient trivial d'implémenter une fonction unionn, qui accepte n'importe quel nombre de tableaux (inspirés par les commentaires de naomik):

// 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) );

Il s'avère que unionn est juste foldl (alias Array.prototype.reduce), qui prend union comme réducteur. Remarque: L'implémentation n'utilisant pas d'accumulateur supplémentaire, une erreur est générée lorsque vous l'appliquez sans argument.

2
user6445533

La méthode la plus simple consiste à utiliser concat() pour fusionner les tableaux, puis filter() pour supprimer les doublons, ou à utiliser concat(), puis à placer le tableau fusionné dans un Set().

Première manière: 

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]

Deuxième manière (mais avec des implications de performance sur l'interface utilisateur):

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
Stelios Voskos

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

Mettre à jour

Voir le code de travail.

http://jsfiddle.net/UAxJa/1/

2
Richard Ayotte

En supposant que les tableaux originaux ne nécessitent pas de déduplication, cela devrait être assez rapide, conserver l'ordre d'origine et ne pas modifier les tableaux d'origine ...

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

usage:

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

console.log(array3);
//-> [ 'Vijendra', 'Singh', 'Shakya' ]
2
Billy Moon

Solution syndicale basée sur ES6

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

2
Vahid Akhtar

Fusionner un nombre illimité de tableaux ou non-tableaux et le garder unique:

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
TxRegex

semble que la réponse acceptée est la plus lente de mes tests;

note Je suis en train de fusionner 2 tableaux d'objets par Clé

<!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
Omu

La solution la plus simple avec filtre:

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

var mergedArrayWithoutDuplicates = array1.concat(
  array2.filter(seccondArrayItem => !array1.includes(seccondArrayItem))
);
2
Jackkobec

DeDuplicate single ou Fusionner et DeDuplicate plusieurs entrées de tableau. Exemple ci-dessous.

utilisation de ES6 - Set, for of, destructuring

J'ai écrit cette fonction simple qui prend plusieurs arguments de tableau . Cette fonction ne concatène pas les valeurs en double dans un seul tableau afin de pouvoir les supprimer ultérieurement.

COURTE DEFINITION DE LA FONCTION (seulement 9 lignes)

/**
* 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);
}

EXEMPLE D'UTILISATION 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
DevWL

Une autre approche pour votre examen avec réduire la fonction:

function mergeDistinct(arResult, candidate){
  if (-1 == arResult.indexOf(candidate)) {
    arResult.Push(candidate);
  }
  return arResult;
}

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

var arMerge = [];
arMerge = array1.reduce(mergeDistinct, arMerge);
arMerge = array2.reduce(mergeDistinct, arMerge);//["Vijendra","Singh","Shakya"];
1
Dmitry Ragozin

Ceci est simple et peut être fait en une seule ligne avec jQuery:

var arr1 = ['Vijendra', 'Singh'], arr2 =['Singh', 'Shakya'];

$.unique(arr1.concat(arr2))//one line

["Vijendra", "Singh", "Shakya"]
1
ucefkh

Une solution en ligne pour relier LiraNuna:

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

// Merges both arrays
let array3 = array1.concat(array2); 

//REMOVE DUPLICATE
let removeDuplicate = [...new Set(array3)];
console.log(removeDuplicate);
1
Jonca33

Voici un exemple simple:

var unique = function(array) {
    var unique = []
    for (var i = 0; i < array.length; i += 1) {
        if (unique.indexOf(array[i]) == -1) {
            unique.Push(array[i])
        }
    }
    return unique
}

var uniqueList = unique(["AAPL", "MSFT"].concat(["MSFT", "BBEP", "GE"]));

Nous définissons unique(array) pour supprimer les éléments redondants et utilisons la fonction concat pour combiner deux tableaux.

1
Zorayr
var MergeArrays=function(arrayOne, arrayTwo, equalityField) {
    var mergeDictionary = {};

    for (var i = 0; i < arrayOne.length; i++) {
        mergeDictionary[arrayOne[i][equalityField]] = arrayOne[i];
    }

    for (var i = 0; i < arrayTwo.length; i++) {
        mergeDictionary[arrayTwo[i][equalityField]] = arrayTwo[i];
    }

    return $.map(mergeDictionary, function (value, key) { return value });
}

En utilisant les dictionnaires et Jquery, vous pouvez fusionner les deux tableaux sans obtenir de doublons. Dans mon exemple, j'utilise un champ donné sur l'objet, mais ce pourrait être simplement l'objet lui-même. 

1
Zach Lewis

Utiliser Lodash

La réponse de @ GijsjanB m'a parue utile, mais mes tableaux contenaient des objets comportant de nombreux attributs. J'ai donc dû les dédoublonner à l'aide de l'un des attributs.

Voici ma solution en utilisant lodash

userList1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
userList2 = [{ id: 3 }, { id: 4 }, { id: 5 }]
// id 3 is repeated in both arrays

users = _.unionWith(userList1, userList2, function(a, b){ return a.id == b.id });

// users = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]

La fonction que vous transmettez au troisième paramètre a deux arguments (deux éléments) et doit renvoyer true s’ils sont égaux. 

1
Felo Vilches

J'ai appris un moyen peu effronté de concaténer deux tableaux avec l'opérateur de propagation:

var array1 = ['tom', 'dick', 'harry'];
var array2 = ['martin', 'ricky'];

array1.Push(...array2);

L'opérateur spread "..." divise le tableau suivant en éléments individuels, puis Push peut les traiter comme des arguments distincts.

1
Lightfooted

Ceci est ma deuxième réponse, mais je crois que le plus rapide? J'aimerais que quelqu'un vérifie pour moi et réponde dans les commentaires.

Ma première tentative a touché environ 99k ops/sec et cela indique 390 ops/sec contre l'autre test jsperf de 140k (pour moi).

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

J'ai essayé de minimiser le plus possible les interactions entre les tableaux cette fois-ci et il semblait que je percevais des performances.

function findMerge(a1, a2) {
    var len1 = a1.length;

    for (var x = 0; x < a2.length; x++) {
        var found = false;

        for (var y = 0; y < len1; y++) {
            if (a2[x] === a1[y]) {
                found = true;
                break;
            }
        }

        if(!found){
            a1.Push(a2.splice(x--, 1)[0]);
        }
    }

    return a1;
}

Edit: j’ai apporté quelques modifications à ma fonction, et la performance est drastique comparée à d’autres sur le site jsperf.

1
David Kirk

Si vous ne souhaitez pas dupliquer une propriété spécifique (par exemple l'ID)

let noDuplicate = array1.filter ( i => array2.findIndex(a => i.id==a.id)==-1 );
let result = [...noDuplicate, ...array2];
1
priolo priolus

Si vous souhaitez rechercher des objets uniques, utilisez JSON.stringify dans votre comparaison. 

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(JSON.stringify(a[i]) === JSON.stringify(a[j]))
                a.splice(j--, 1);
        }
    }

    return a;
}
1
Jason Matthews

Voici le plus efficace, en termes de temps de calcul. En outre, il conserve l'ordre initial des éléments.

Filtrez d'abord tous les doublons du deuxième tableau, puis concaténez ce qui reste au premier.

var a = [1,2,3];
var b = [5,4,3];
var c = a.concat(b.filter(function(i){
    return a.indexOf(i) == -1;
}));
console.log(c); // [1, 2, 3, 5, 4]

Voici une version légèrement améliorée (plus rapide) de celle-ci, avec un inconvénient: les tableaux ne doivent pas manquer de valeurs:

var i, c = a.slice(), ci = c.length;
for(i = 0; i < b.length; i++){
    if(c.indexOf(b[i]) == -1)
        c[ci++] = b[i];
}
1
AlexTR
Array.prototype.union = function (other_array) {
/* you can include a test to check whether other_array really is an array */
  other_array.forEach(function(v) { if(this.indexOf(v) === -1) {this.Push(v);}}, this);    
}
1
StickyBandit

var array1 = ["one","two"];
var array2 = ["two", "three"];
var collectionOfTwoArrays = [...array1, ...array2];    
var uniqueList = array => [...new Set(array)];
console.log('Collection :');
console.log(collectionOfTwoArrays);    
console.log('Collection without duplicates :');
console.log(uniqueList(collectionOfTwoArrays));

0
Shiva
  • Une méthode moderne pour y parvenir consiste simplement à utiliser le OP&EACUTE;RATEUR DE PROPAGATION.
  • Et pour éviter les doublons, nous pouvons utiliser efficacement SETS; Les ensembles ne permettent pas les doublons par défaut.
  • Pour obtenir une sortie sous forme de tableau à partir d'un Set, nous pouvons utiliser ARRAY.FROM ()

Alors, voici une démonstration de votre scénario - 

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

0
Tushar Walzade

ES2019

Vous pouvez l'utiliser comme union(array1, array2, array3, ...)

/**
 * Merges two or more arrays keeping unique items. This method does
 * not change the existing arrays, but instead returns a new array.
 */
function union<T>(...arrays: T[]) {
  return [...new Set([...arrays].flat())];
}

Il s'agit de ES2019 en raison de la fonction flat(), mais vous pouvez utiliser core-js pour l'obtenir sous forme de fichier polyfill. Le T ici est un type générique TypeScript, que vous pouvez supprimer si vous n'utilisez pas TypeScript. Si vous utilisez TypeScript, veillez à ajouter "lib": ["es2019.array"] aux options du compilateur dans tsconfig.json.

ou...

utilisez simplement lodash _. union

0
orad

Modulaire, général

Cela pourrait être réalisé en composant deux fonctions essentielles.

const getUniqueMerge = (...arrs) => getUniqueArr(mergeArrs(...arrs))
const getUniqueArr = (array) => Array.from(new Set(array))  
const mergeArrs = (...arrs) => [].concat(...arrs)

Il peut gérer un nombre illimité de tableaux ou de valeurs

console.log(getUniqueMerge(["Vijendra","Singh"],["Singh", "Shakya"])
// ["Vijendra", "Singh", "Shakya"]

console.log(getUniqueMerge(["Sheldon", "Cooper"], ["and", "Cooper", "Amy", "and"], "Farrah", "Amy", "Fowler"))
// ["Sheldon", "Cooper", "and", "Amy", "Farrah", "Fowler"]
0
Ben Carp

Je pense que cela fonctionne plus vite.

removeDup = a => {

for (let i = a.length - 1; i >= 0; i--) {
    for (let j = i-1; j >= 0; j--) {
        if (a[i] === a[j])
            a.splice(j--, 1);
    }
}

return a;

}

0
Muhammad

Si, comme moi, vous devez prendre en charge les anciens navigateurs, cela fonctionne avec IE6 +.

function es3Merge(a, b) {
    var hash = {},
        i = (a = a.slice(0)).length,
        e;

    while (i--) {
        hash[a[i]] = 1;
    }

    for (i = 0; i < b.length; i++) {
        hash[e = b[i]] || a.Push(e);
    }

    return a;
};

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

0
Stephen S

Voici ma solution https://Gist.github.com/4692150 avec un résultat égal et simple à utiliser:

function merge_arrays(arr1,arr2)
{
   ... 
   return {first:firstPart,common:commonString,second:secondPart,full:finalString}; 
}

console.log(merge_arrays(
[
[1,"10:55"] ,
[2,"10:55"] ,
[3,"10:55"]
],[
[3,"10:55"] ,
[4,"10:55"] ,
[5,"10:55"]
]).second);

result:
[
[4,"10:55"] ,
[5,"10:55"]
]
0
Shimon Doodkin

Vous pouvez essayer ceci:

const union = (a, b) => Array.from(new Set([...a, ...b]));

console.log(union(["neymar","messi"], ["ronaldo","neymar"]));

0
mitesh7172
Array.prototype.pushUnique = function(values)
{
    for (var i=0; i < values.length; i++)
        if (this.indexOf(values[i]) == -1)
            this.Push(values[i]);
};

Essayer:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
array1.pushUnique(array2);
alert(array1.toString());  // Output: Vijendra,Singh,Shakya
0
StanE

Utilisation: https://Gist.github.com/samad-aghaei/7250ffb74ed80732debb1cbb14d2bfb0

var _uniqueMerge = function(opts, _ref){
    for(var key in _ref)
        if (_ref && _ref[key] && _ref[key].constructor && _ref[key].constructor === Object)
          _ref[key] = _uniqueMerge((opts ? opts[key] : null), _ref[key] );
        else if(opts && opts.hasOwnProperty(key))
          _ref[key] = opts[key];
        else _ref[key] = _ref[key][1];
    return _ref;
}
0
Samad Aghaei

Si vous utilisez uniquement underscore.js, il n'a pas unionWith, unionBy

vous pouvez essayer: _.uniq(_.union(arr1, arr2), (obj) => obj.key) (key est le paramètre clé de chaque objet) Cela devrait aider à devenir unique après l'union des deux tableaux.

0
Vivek Parekh

Juste écrit avant pour la même raison (fonctionne avec n'importe quel nombre de tableaux):

/**
 * Returns with the union of the given arrays.
 *
 * @param Any amount of arrays to be united.
 * @returns {array} The union array.
 */
function uniteArrays()
{
    var union = [];
    for (var argumentIndex = 0; argumentIndex < arguments.length; argumentIndex++)
    {
        eachArgument = arguments[argumentIndex];
        if (typeof eachArgument !== 'array')
        {
            eachArray = eachArgument;
            for (var index = 0; index < eachArray.length; index++)
            {
                eachValue = eachArray[index];
                if (arrayHasValue(union, eachValue) == false)
                union.Push(eachValue);
            }
        }
    }

    return union;
}    

function arrayHasValue(array, value)
{ return array.indexOf(value) != -1; }
0
Geri

La meilleure et la plus simple consiste à utiliser la fonction "some ()" de JavaScript qui renvoie true ou false indiquant si le tableau contient l'élément de l'objet. Vous pouvez faire ceci:

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

var array3 = array1;

array2.forEach(function(elementArray2){
    var isEquals = array1.some(function(elementArray1){
        return elementArray1 === elementArray2;
    })
    if(!isEquals){
        array3.Push(elementArray2);
    }
});
console.log(array3);

Les resultats: 

["Vijendra", "Singh", "Shakya"]

ss vous le souhaitez ... sans le dupliquer ...

0
Thiago Araújo