Question Comment fusionner deux tableaux dans JavaScript et dédupliquer des éléments


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 des mots répétés supprimés.

Comment puis-je fusionner deux tableaux dans JavaScript afin que je reçois uniquement les éléments uniques de chaque tableau dans le même ordre qu'ils ont été insérés dans les tableaux d'origine?


976
2017-10-18 08:34


origine


Réponses:


Pour fusionner les tableaux (sans supprimer les doublons)

Utilisation de la version ES5 Array.concat:

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

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

Utilisation de la version ES6 déstructuration

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

Comme il n'y a pas de méthode intégrée pour supprimer les doublons (ECMA-262 a effectivement Array.forEach ce qui serait génial 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 permettra également de préserver l'ordre des tableaux (c'est-à-dire, aucun tri nécessaire).

Comme beaucoup de gens sont ennuyés par l'augmentation du prototype de Array.prototype et for in boucles, 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 où ES5 est disponible, vous pouvez utiliser Object.defineProperty comme ça:

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

1233
2017-10-18 08:42



Avec Underscore.js ou Lo-Dash vous pouvez faire:

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

http://underscorejs.org/#union

http://lodash.com/docs#union


510
2018-05-08 13:24



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 performante serait de filtrer les éléments uniques b avant de 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]

193
2018-04-15 10:08



Ceci est une solution ECMAScript 6 utilisant opérateur de propagation et les génériques de tableau.

Actuellement, il 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))];
}

119
2017-12-27 06:28



ES6

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

OU

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

OU

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

86
2017-08-14 08:08



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

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

Un commentaire indiquait que l'une de mes variables d'installation faisait que ma boucle devançait le reste, parce qu'elle n'avait pas besoin d'initialiser un tableau vide pour écrire. Je suis d'accord avec cela, donc j'ai réécrit le test même sur le terrain de jeu, et inclus une option encore plus rapide.

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

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

La meilleure réponse ici avec la double boucle sur chaque valeur (i-1) est toujours significativement plus lente. Lodash est toujours très performant, et je le recommanderais toujours à tous ceux qui ne voient pas d'inconvénient à ajouter une bibliothèque à leur 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 forte visibilité ici, en battant tout sur mes tests avec le dernier Canary Chrome (44.0.2360) à ce jour.

Check-out La réponse de Mike et La réponse de Dan Stocker si vous voulez l'augmenter d'un cran en vitesse. Ce sont de loin les plus rapides de tous les résultats après avoir passé à travers presque toutes les réponses viables.


30
2017-08-04 14:14



Utilisant un Ensemble (ECMAScript 2015), ce sera aussi simple que ça:

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

27
2018-01-06 19:05



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 le opérateur de propagation pour concaténer le tableau.
  • Utilisation Ensemble pour créer un ensemble distinct d'éléments.
  • Utilisez à nouveau l'opérateur spread pour convertir l'ensemble en un tableau.

26
2018-04-07 07:26