Comment obtenir la différence entre deux tableaux en Javascript?

Existe-t-il un moyen de renvoyer la différence entre deux tableaux en JavaScript?

Par exemple:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

// need ["c", "d"]

Tout conseil grandement apprécié.

484
demandé sur Flip 2009-07-27 14:38:50

30 réponses

Je suppose que vous comparez un tableau normal. Si ce n'est pas le cas, vous devez changer la boucle for en for .. dans la boucle.

function arr_diff (a1, a2) {

    var a = [], diff = [];

    for (var i = 0; i < a1.length; i++) {
        a[a1[i]] = true;
    }

    for (var i = 0; i < a2.length; i++) {
        if (a[a2[i]]) {
            delete a[a2[i]];
        } else {
            a[a2[i]] = true;
        }
    }

    for (var k in a) {
        diff.push(k);
    }

    return diff;
}

console.log(arr_diff(['a', 'b'], ['a', 'b', 'c', 'd']));
console.log(arr_diff("abcd", "abcde"));
console.log(arr_diff("zxc", "zxc"));

Une meilleure solution, si vous ne vous souciez pas de la rétrocompatibilité, est d'utiliser le filtre. Mais encore, cette solution fonctionne.

152
répondu Thinker 2017-12-07 20:52:26
Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

////////////////////  
// Examples  
////////////////////

[1,2,3,4,5,6].diff( [3,4,5] );  
// => [1, 2, 6]

["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);  
// => ["test5", "test6"]

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return a.indexOf(i) < 0;});
};

////////////////////  
// Examples  
////////////////////

var dif1 = [1,2,3,4,5,6].diff( [3,4,5] );  
console.log(dif1); // => [1, 2, 6]


var dif2 = ["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);  
console.log(dif2); // => ["test5", "test6"]

Note indexOf et filter ne sont pas disponibles dans ie avant ie9.

770
répondu Joshaven Potter 2018-01-17 20:54:45

Il y a une meilleure façon d'utiliser ES7:

Intersection

 let intersection = arr1.filter(x => arr2.includes(x));

Différence d'Intersection diagramme de Venn

Pour [1,2,3] [2,3] obtenir [2,3]. D'autre part, pour [1,2,3] [2,3,5] retournera la même chose.

Différence

let difference = arr1.filter(x => !arr2.includes(x));

Diagramme de Venn de différence droite

Pour [1,2,3] [2,3] obtenir [1]. D'autre part, pour [1,2,3] [2,3,5] retournera la même chose.

Pour une différence symétrique , Vous pouvez faire:

let difference = arr1
                 .filter(x => !arr2.includes(x))
                 .concat(arr2.filter(x => !arr1.includes(x)));

Différence symétrique diagramme de Venn

De Cette façon, vous obtiendrez un tableau contenant tous les éléments de arr1 qui ne sont pas dans arr2 et vice-versa

Comme @ Joshaven Potter l'a souligné dans sa réponse, vous pouvez ajouter ceci au tableau.prototype de sorte qu'il peut être utilisé comme ceci:

Array.prototype.diff = arr1.filter(x => arr2.includes(x));
[1, 2, 3].diff([2, 3])
503
répondu Luis Sieira 2018-06-15 09:01:31

C'est de loin le moyen le plus simple d'obtenir exactement le résultat que vous recherchez, en utilisant jQuery:

var diff = $(old_array).not(new_array).get();

diff contient maintenant ce qu'il a dans old_array, ce qui n'est pas dans new_array

289
répondu superphonic 2014-08-21 09:45:47

La méthode de différence dans Underscore (ou son remplacement drop-in, Lo-Dash) peut le faire aussi:

(R)eturns the values from array that are not present in the other arrays

_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]

Comme pour toute fonction de soulignement, vous pouvez également l'utiliser dans un style plus orienté objet:

_([1, 2, 3, 4, 5]).difference([5, 2, 10]);
141
répondu mahemoff 2013-12-19 17:02:45

JavaScript Simple

Il y a deux intégrations possibles pour "différence". Je vous laisse choisir celui que vous voulez. Dites que vous avez:

var a1 = ['a', 'b'     ];
var a2 = [     'b', 'c'];
  1. Si vous voulez obtenir ['a'], Utilisez cette fonction:

    function difference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      return result;
    }
    
  2. Si vous voulez obtenir ['a', 'c'] (tous les éléments contenus dans soit a1 ou a2, mais pas les deux - la soi-disant différence symétrique ), utilisez cette fonction:

    function symmetricDifference(a1, a2) {
      var result = [];
      for (var i = 0; i < a1.length; i++) {
        if (a2.indexOf(a1[i]) === -1) {
          result.push(a1[i]);
        }
      }
      for (i = 0; i < a2.length; i++) {
        if (a1.indexOf(a2[i]) === -1) {
          result.push(a2[i]);
        }
      }
      return result;
    }
    

Lodash / Soulignement

Si vous utilisez lodash, vous pouvez utiliser _.difference(a1, a2) (cas 1 ci-dessus) ou _.xor(a1, a2) (cas 2).

Si vous utilisez un trait de soulignement.js, vous pouvez utiliser le _.difference(a1, a2) fonction pour le cas 1.

ES6 Set, pour les très grands tableaux

Le code ci-dessus fonctionne sur tous les navigateurs. Cependant, pour les grands tableaux de plus d'environ 10 000 éléments, il devient assez lent, car il a une complexité O (n2). Sur de nombreux navigateurs modernes, nous pouvons profiter de l'ES6 Set objet pour accélérer les choses. Lodash utilise automatiquement Set lorsqu'il est disponible. Si vous n'utilisez pas lodash, utilisez l'implémentation suivante, inspirée par le billet de blog D'Axel Rauschmayer :

function difference(a1, a2) {
  var a2Set = new Set(a2);
  return a1.filter(function(x) { return !a2Set.has(x); });
}

function symmetricDifference(a1, a2) {
  return difference(a1, a2).concat(difference(a2, a1));
}

Notes

Le comportement de tous les exemples peut être surprenant ou non évident si vous vous souciez de -0, +0, NaN ou matrices creuses. (Pour la plupart des utilisations, cela n'a pas d'importance.)

61
répondu Jo Liss 2016-01-21 12:17:33

Vous pouvez utiliser un Set dans ce cas. Il est optimisé pour ce type d'opération (union, intersection, différence).

Assurez-vous qu'il s'applique à votre cas, une fois qu'il n'autorise aucun doublon.

var a = new JS.Set([1,2,3,4,5,6,7,8,9]);
var b = new JS.Set([2,4,6,8]);

a.difference(b)
// -> Set{1,3,5,7,9}
32
répondu Samuel Carrijo 2009-07-27 10:43:55
function diff(a1, a2) {
  return a1.concat(a2).filter(function(val, index, arr){
    return arr.indexOf(val) === arr.lastIndexOf(val);
  });
}

Fusionner les deux tableaux, les valeurs uniques n'apparaîtront qu'une seule fois donc indexOf() sera le même que lastIndexOf().

24
répondu pdbrito 2015-07-06 16:10:05

Pour soustraire un tableau d'un autre, utilisez simplement l'extrait ci-dessous:

var a1 = ['1','2','3','4','6'];
var a2 = ['3','4','5'];

var items = new Array();

items = jQuery.grep(a1,function (item) {
    return jQuery.inArray(item, a2) < 0;
});

Il sera de retour ['1,'2','6'] ce sont des éléments du premier tableau qui n'existent pas dans le second.

Par conséquent, selon votre échantillon de problème, le code suivant est la solution exacte:

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var _array = new Array();

_array = jQuery.grep(array2, function (item) {
     return jQuery.inArray(item, array1) < 0;
});
17
répondu Kradle___ 2011-11-21 11:34:28

Une solution utilisant indexOf() sera correcte pour les petits tableaux mais à mesure qu'ils grandissent en longueur, les performances de l'algorithme approchent O(n^2). Voici une solution qui fonctionnera mieux pour les très grands tableaux en utilisant des objets comme tableaux associatifs pour stocker les entrées du tableau en tant que clés; elle élimine également les entrées en double automatiquement mais ne fonctionne qu'avec des valeurs de chaîne (ou des valeurs qui peuvent être stockées en toute sécurité en tant que Chaînes):

function arrayDiff(a1, a2) {
  var o1={}, o2={}, diff=[], i, len, k;
  for (i=0, len=a1.length; i<len; i++) { o1[a1[i]] = true; }
  for (i=0, len=a2.length; i<len; i++) { o2[a2[i]] = true; }
  for (k in o1) { if (!(k in o2)) { diff.push(k); } }
  for (k in o2) { if (!(k in o1)) { diff.push(k); } }
  return diff;
}

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
arrayDiff(a1, a2); // => ['c', 'd']
arrayDiff(a2, a1); // => ['c', 'd']
12
répondu maerics 2012-05-15 15:22:23

Approche fonctionnelle avec ES2015

Calculer le difference entre deux tableaux est l'une des opérations Set. Le terme indique déjà que le type natif Set doit être utilisé, afin d'augmenter la vitesse de recherche. Quoi qu'il en soit, il y a trois permutations lorsque vous calculez la différence entre deux ensembles:

[+left difference] [-intersection] [-right difference]
[-left difference] [-intersection] [+right difference]
[+left difference] [-intersection] [+right difference]

Voici une solution fonctionnelle qui reflète ces permutations.

Gauche difference:

// small, reusable auxiliary functions

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


// left difference

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


// mock data

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


// run the computation

console.log( differencel(xs) (ys) );

Droite difference:

differencer est trivial. C'est juste differencel avec des arguments inversés. Vous pouvez écrire une fonction pour plus de commodité: const differencer = flip(differencel). C'est tout!

Symétrique difference:

Maintenant que nous avons le gauche et le droit, l'implémentation du difference symétrique devient également triviale:

// small, reusable auxiliary functions

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


// left difference

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


// symmetric difference

const difference = ys => xs =>
 concat(differencel(xs) (ys)) (flip(differencel) (xs) (ys));

// mock data

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


// run the computation

console.log( difference(xs) (ys) );

Je suppose que cet exemple est un bon point de départ pour obtenir une impression de ce que signifie la programmation fonctionnelle:

Programmation avec des blocs de construction qui peuvent être branchés ensemble de différentes façons.

11
répondu ftor 2016-10-11 16:00:30

Avec L'arrivée D'ES6 avec sets et splat operator (au moment d'être fonctionne uniquement dans Firefox, Vérifiez Tableau de compatibilité), Vous pouvez écrire le suivant liner:

var a = ['a', 'b', 'c', 'd'];
var b = ['a', 'b'];
var b1 = new Set(b);
var difference = [...new Set([...a].filter(x => !b1.has(x)))];

Qui se traduira par [ "c", "d" ].

10
répondu Salvador Dali 2015-01-17 07:15:09

La réponse ci-dessus de Joshaven Potter est géniale. Mais il renvoie des éléments dans le tableau B qui ne sont pas dans le tableau C, mais pas l'inverse. Par exemple, si var a=[1,2,3,4,5,6].diff( [3,4,5,7]); alors il affichera: ==> [1,2,6], mais Pas [1,2,6,7], Quelle est la différence réelle entre les deux. Vous pouvez toujours utiliser le code de Potter ci-dessus mais simplement refaire la comparaison une fois en arrière:

Array.prototype.diff = function(a) {
    return this.filter(function(i) {return !(a.indexOf(i) > -1);});
};

////////////////////  
// Examples  
////////////////////

var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
var b=[3,4,5,7].diff([1,2,3,4,5,6]);
var c=a.concat(b);
console.log(c);

Cela devrait produire: [ 1, 2, 6, 7 ]

9
répondu user1685068 2012-09-21 08:28:54

Une Autre façon de résoudre le problème

function diffArray(arr1, arr2) {
    return arr1.concat(arr2).filter(function (val) {
        if (!(arr1.includes(val) && arr2.includes(val)))
            return val;
    });
}

diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]);    // return [7, 4, 5]
8
répondu Iurii Golskyi 2016-11-02 20:25:55
Array.prototype.difference = function(e) {
    return this.filter(function(i) {return e.indexOf(i) < 0;});
};

eg:- 

[1,2,3,4,5,6,7].difference( [3,4,5] );  
 => [1, 2, 6 , 7]
7
répondu riyas tk 2015-07-07 14:55:28

Solution très Simple avec la fonction de filtre de JavaScript:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

function diffArray(arr1, arr2) {
  var newArr = [];
  var myArr = arr1.concat(arr2);
  
    newArr = myArr.filter(function(item){
      return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0;
    });
   alert(newArr);
}

diffArray(a1, a2);
6
répondu Yash Thakkar 2017-04-11 21:56:49

Que diriez-vous de ceci:

Array.prototype.contains = function(needle){
  for (var i=0; i<this.length; i++)
    if (this[i] == needle) return true;

  return false;
} 

Array.prototype.diff = function(compare) {
    return this.filter(function(elem) {return !compare.contains(elem);})
}

var a = new Array(1,4,7, 9);
var b = new Array(4, 8, 7);
alert(a.diff(b));

Donc, de cette façon, vous pouvez faire array1.diff(array2) pour obtenir leur différence (Horrible complexité temporelle pour l'algorithme si-O ( array1.longueur x matrice2.longueur) je crois)

5
répondu Cat 2010-08-05 21:29:37

En utilisant http://phrogz.net/JS/ArraySetMath.js vous pouvez:

var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];

var array3 = array2.subtract( array1 );
// ["test5", "test6"]

var array4 = array1.exclusion( array2 );
// ["test5", "test6"]
4
répondu Phrogz 2011-01-25 18:21:10
  • solution JavaScript Pure (pas de bibliothèques)
  • Compatible avec les anciens navigateurs (n'utilise pas filter)
  • O (N ^ 2)
  • facultatif fn paramètre de rappel qui vous permet de spécifier comment comparer les éléments du tableau

function diff(a, b, fn){
    var max = Math.max(a.length, b.length);
        d = [];
    fn = typeof fn === 'function' ? fn : false
    for(var i=0; i < max; i++){
        var ac = i < a.length ? a[i] : undefined
            bc = i < b.length ? b[i] : undefined;
        for(var k=0; k < max; k++){
            ac = ac === undefined || (k < b.length && (fn ? fn(ac, b[k]) : ac == b[k])) ? undefined : ac;
            bc = bc === undefined || (k < a.length && (fn ? fn(bc, a[k]) : bc == a[k])) ? undefined : bc;
            if(ac == undefined && bc == undefined) break;
        }
        ac !== undefined && d.push(ac);
        bc !== undefined && d.push(bc);
    }
    return d;
}

alert(
    "Test 1: " + 
    diff(
        [1, 2, 3, 4],
        [1, 4, 5, 6, 7]
      ).join(', ') +
    "\nTest 2: " +
    diff(
        [{id:'a',toString:function(){return this.id}},{id:'b',toString:function(){return this.id}},{id:'c',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        [{id:'a',toString:function(){return this.id}},{id:'e',toString:function(){return this.id}},{id:'f',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
        function(a, b){ return a.id == b.id; }
    ).join(', ')
);
3
répondu Trevor 2014-09-17 19:57:48

Cela fonctionne: fusionnez fondamentalement les deux tableaux, recherchez les doublons et poussez ce qui n'est pas dupliqué dans un nouveau tableau qui fait la différence.

function diff(arr1, arr2) {
  var newArr = [];
  var arr = arr1.concat(arr2);
  
  for (var i in arr){
    var f = arr[i];
    var t = 0;
    for (j=0; j<arr.length; j++){
      if(arr[j] === f){
        t++; 
        }
    }
    if (t === 1){
      newArr.push(f);
        }
  } 
  return newArr;
}
3
répondu Giorgio Giuliani 2015-08-01 10:33:24
function diffArray(arr1, arr2) {
  var newArr = arr1.concat(arr2);
  return newArr.filter(function(i){
    return newArr.indexOf(i) == newArr.lastIndexOf(i);
  });
}

Cela fonctionne pour moi

3
répondu Stan D 2016-05-05 14:24:28

Je réfléchis... pour le bien d'un défi; -) serait ce travail... (pour les tableaux de base de chaînes, de nombres, etc.) pas de tableaux imbriqués

function diffArrays(arr1, arr2, returnUnion){
  var ret = [];
  var test = {};
  var bigArray, smallArray, key;
  if(arr1.length >= arr2.length){
    bigArray = arr1;
    smallArray = arr2;
  } else {
    bigArray = arr2;
    smallArray = arr1;
  }
  for(var i=0;i<bigArray.length;i++){
    key = bigArray[i];
    test[key] = true;
  }
  if(!returnUnion){
    //diffing
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = null;
      }
    }
  } else {
    //union
    for(var i=0;i<smallArray.length;i++){
      key = smallArray[i];
      if(!test[key]){
        test[key] = true;
      }
    }
  }
  for(var i in test){
    ret.push(i);
  }
  return ret;
}

array1 = "test1", "test2","test3", "test4", "test7"
array2 = "test1", "test2","test3","test4", "test5", "test6"
diffArray = diffArrays(array1, array2);
//returns ["test5","test6","test7"]

diffArray = diffArrays(array1, array2, true);
//returns ["test1", "test2","test3","test4", "test5", "test6","test7"]

Remarque le tri ne sera probablement pas comme indiqué ci-dessus... mais si vous le souhaitez, appel .sort() sur le tableau à trier.

2
répondu scunliffe 2009-07-27 11:11:13

Littlebit correctif pour la meilleure réponse

function arr_diff(a1, a2)
{
  var a=[], diff=[];
  for(var i=0;i<a1.length;i++)
    a[a1[i]]=a1[i];
  for(var i=0;i<a2.length;i++)
    if(a[a2[i]]) delete a[a2[i]];
    else a[a2[i]]=a2[i];
  for(var k in a)
   diff.push(a[k]);
  return diff;
}

Cela prendra en considération le type d'élément actuel. B / C lorsque nous faisons un [a1[i]] il convertit une valeur en chaîne de sa valeur oroginale, donc nous avons perdu la valeur réelle.

2
répondu Vedanta-krit das 2012-04-18 06:43:40

Cela a été inspiré par la réponse acceptée par Thinker, mais la réponse de Thinker semble supposer que les tableaux sont des ensembles. Il tombe en morceaux si les tableaux sont [ "1", "2" ] et [ "1", "1", "2", "2" ]

La différence entre ces tableaux est [ "1", "2" ]. La solution suivante est O (n * n), donc pas idéale, mais si vous avez de grands tableaux, elle présente également des avantages en mémoire par rapport à la solution de Thinker.

Si vous avez affaire à des ensembles en premier lieu, la solution de Thinker est définitivement meilleure. Si vous avez une version récente de Javascript avec accès aux filtres, vous devriez les utiliser aussi. Ceci est seulement pour ceux qui ne traitent pas avec des ensembles et utilisent une ancienne version de JavaScript (pour une raison quelconque)...

if (!Array.prototype.diff) { 
    Array.prototype.diff = function (array) {
        // if the other array is a falsy value, return a copy of this array
        if ((!array) || (!Array.prototype.isPrototypeOf(array))) { 
            return this.slice(0);
        }

        var diff = [];
        var original = this.slice(0);

        for(var i=0; i < array.length; ++i) {
            var index = original.indexOf(array[i]);
            if (index > -1) { 
                original.splice(index, 1);
            } else { 
                diff.push(array[i]);
            }
        }

        for (var i=0; i < original.length; ++i) {
            diff.push(original[i]);
        }
        return diff;
    }
}   
2
répondu redusek 2014-01-30 17:25:36
function diff(arr1, arr2) {
  var filteredArr1 = arr1.filter(function(ele) {
    return arr2.indexOf(ele) == -1;
  });

  var filteredArr2 = arr2.filter(function(ele) {
    return arr1.indexOf(ele) == -1;
  });
  return filteredArr1.concat(filteredArr2);
}

diff([1, "calf", 3, "piglet"], [1, "calf", 3, 4]); // Log ["piglet",4]
2
répondu huy-tran 2016-02-08 06:57:50

Si les tableaux ne sont pas de types simples, alors l'une des réponses ci-dessus peut être adaptée:

Array.prototype.diff = function(a) {
        return this.filter(function(i) {return a.map(function(e) { return JSON.stringify(e); }).indexOf(JSON.stringify(i)) < 0;});
    };

Cette méthode fonctionne sur des tableaux d'objets complexes.

2
répondu Vadim 2017-10-25 09:06:50

Pour obtenir le symétrique différence, vous devez comparer les tableaux dans les deux sens (ou de toutes les façons dans le cas de plusieurs tableaux)

entrez la description de l'image ici


ES7 (ECMAScript 2016)

// diff between just two arrays:
function arrayDiff(a, b) {
    return [
        ...a.filter(x => !b.includes(x)),
        ...b.filter(x => !a.includes(x))
    ];
}

// diff between multiple arrays:
function arrayDiff(...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter(x => !unique.includes(x));
    }));
}

ES6 (ECMAScript 2015)

// diff between just two arrays:
function arrayDiff(a, b) {
    return [
        ...a.filter(x => b.indexOf(x) === -1),
        ...b.filter(x => a.indexOf(x) === -1)
    ];
}

// diff between multiple arrays:
function arrayDiff(...arrays) {
    return [].concat(...arrays.map( (arr, i) => {
        const others = arrays.slice(0);
        others.splice(i, 1);
        const unique = [...new Set([].concat(...others))];
        return arr.filter(x => unique.indexOf(x) === -1);
    }));
}

ES5 (ECMAScript 5.1)

// diff between just two arrays:
function arrayDiff(a, b) {
    var arrays = Array.prototype.slice.call(arguments);
    var diff = [];

    arrays.forEach(function(arr, i) {
        var other = i === 1 ? a : b;
        arr.forEach(function(x) {
            if (other.indexOf(x) === -1) {
                diff.push(x);
            }
        });
    })

    return diff;
}

// diff between multiple arrays:
function arrayDiff() {
    var arrays = Array.prototype.slice.call(arguments);
    var diff = [];

    arrays.forEach(function(arr, i) {
        var others = arrays.slice(0);
        others.splice(i, 1);
        var otherValues = Array.prototype.concat.apply([], others);
        var unique = otherValues.filter(function (x, j) { 
            return otherValues.indexOf(x) === j; 
        });
        diff = diff.concat(arr.filter(x => unique.indexOf(x) === -1));
    });
    return diff;
}

Exemple:

// diff between two arrays:
const a = ['a', 'd', 'e'];
const b = ['a', 'b', 'c', 'd'];
arrayDiff(a, b); // (3) ["e", "b", "c"]

// diff between multiple arrays
const a = ['b', 'c', 'd', 'e', 'g'];
const b = ['a', 'b'];
const c = ['a', 'e', 'f'];
arrayDiff(a, b, c); // (4) ["c", "d", "g", "f"]
2
répondu Luca Borrione 2018-09-21 09:33:43

Je voulais une fonction similaire qui prenait un ancien tableau et un nouveau tableau et me donnait un tableau d'éléments ajoutés et un tableau d'éléments supprimés, et je voulais qu'il soit efficace (donc non .contient!).

, Vous pouvez jouer avec ma solution proposée ici: http://jsbin.com/osewu3/12.

Quelqu'un peut-il voir des problèmes/améliorations à cet algorithme? Merci!

Liste des codes:

function diff(o, n) {
  // deal with empty lists
  if (o == undefined) o = [];
  if (n == undefined) n = [];

  // sort both arrays (or this won't work)
  o.sort(); n.sort();

  // don't compare if either list is empty
  if (o.length == 0 || n.length == 0) return {added: n, removed: o};

  // declare temporary variables
  var op = 0; var np = 0;
  var a = []; var r = [];

  // compare arrays and add to add or remove lists
  while (op < o.length && np < n.length) {
      if (o[op] < n[np]) {
          // push to diff?
          r.push(o[op]);
          op++;
      }
      else if (o[op] > n[np]) {
          // push to diff?
          a.push(n[np]);
          np++;
      }
      else {
          op++;np++;
      }
  }

  // add remaining items
  if( np < n.length )
    a = a.concat(n.slice(np, n.length));
  if( op < o.length )
    r = r.concat(o.slice(op, o.length));

  return {added: a, removed: r}; 
}
1
répondu Ian Grainger 2010-08-13 12:07:33

Je cherchais une réponse simple qui n'impliquait pas l'utilisation de différentes bibliothèques, et j'ai trouvé la mienne que je ne pense pas avoir été mentionnée ici. Je ne sais pas à quel point c'est efficace ou quoi que ce soit mais cela fonctionne;

    function find_diff(arr1, arr2) {
      diff = [];
      joined = arr1.concat(arr2);
      for( i = 0; i <= joined.length; i++ ) {
        current = joined[i];
        if( joined.indexOf(current) == joined.lastIndexOf(current) ) {
          diff.push(current);
        }
      }
      return diff;
    }

Pour mon code, j'ai aussi besoin de doublons, mais je suppose que ce n'est pas toujours préféré.

Je suppose que le principal inconvénient est qu'il compare potentiellement de nombreuses options qui ont déjà été rejetées.

1
répondu Samuel 2011-07-16 04:22:59

En réponse à la personne qui voulait soustraire un tableau d'un autre...

Si pas plus de 1000 éléments, essayez ceci...

Configurez une nouvelle variable pour dupliquer Array01 et appelez-la Array03.

Maintenant, utilisez l'algorithme de tri à bulles pour comparer les éléments de Array01 avec Array02 et chaque fois que vous trouvez une correspondance procédez comme suit à Array03...

 if (Array01[x]==Array02[y]) {Array03.splice(x,1);}

NB: nous modifions Array03 au lieu de Array01 afin de ne pas bousiller les boucles imbriquées de la bulle tri!

Enfin, Copiez le contenu de Array03 à Array01 avec une simple affectation, et vous avez terminé.

1
répondu MPS 2011-07-20 12:20:13