web-dev-qa-db-fra.com

Tableaux Javascript: supprimer tous les éléments contenus dans un autre tableau

Je recherche un moyen efficace de supprimer tous les éléments d'un tableau javascript s'ils sont présents dans un autre tableau.

// If I have this array:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

// and this one:
var toRemove = ['b', 'c', 'g'];

Je veux utiliser myArray pour le laisser dans cet état: ['a', 'd', 'e', 'f']

Avec jQuery, j'utilise grep() et inArray(), ce qui fonctionne bien:

myArray = $.grep(myArray, function(value) {
    return $.inArray(value, toRemove) < 0;
});

Existe-t-il une méthode purement javascript pour le faire sans bouclage ni épissage?

171
Tap

Utilisez la méthode Array.filter() :

myArray = myArray.filter( function( el ) {
  return toRemove.indexOf( el ) < 0;
} );

Petite amélioration, le support du navigateur pour Array.includes() a augmenté:

myArray = myArray.filter( function( el ) {
  return !toRemove.includes( el );
} );

Prochaine adaptation en utilisant fonctions de flèche :

myArray = myArray.filter( ( el ) => !toRemove.includes( el ) );
290
Sirko

La méthode filter devrait faire l'affaire:

const myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
const toRemove = ['b', 'c', 'g'];

// ES5 syntax
const filteredArray = myArray.filter(function(x) { 
  return toRemove.indexOf(x) < 0;
});

Si votre tableau toRemove est grand, ce type de modèle de recherche peut s'avérer inefficace. Il serait plus performant de créer une carte pour que les recherches soient O(1) plutôt que O(n).

const toRemoveMap = toRemove.reduce(
  function(memo, item) {
    memo[item] = memo[item] || true;
    return memo;
  },
  {} // initialize an empty object
);

const filteredArray = myArray.filter(function (x) {
  return toRemoveMap[x];
});

// or, if you want to use ES6-style arrow syntax:
const toRemoveMap = toRemove.reduce((memo, item) => ({
  ...memo,
  [item]: true
}), {});

const filteredArray = myArray.filter(x => toRemoveMap[x]);
27
Ashwin Balamohan

Si vous utilisez un tableau d'objets. Ensuite, le code ci-dessous devrait faire la magie, où une propriété d'objet sera le critère pour supprimer les éléments en double.

Dans l'exemple ci-dessous, les doublons ont été supprimés en comparant le nom de chaque élément.

Essayez cet exemple. http://jsfiddle.net/deepak7641/zLj133rh/

var myArray = [
  {name: 'deepak', place: 'bangalore'}, 
  {name: 'chirag', place: 'bangalore'}, 
  {name: 'alok', place: 'berhampur'}, 
  {name: 'chandan', place: 'mumbai'}
];
var toRemove = [
  {name: 'deepak', place: 'bangalore'},
  {name: 'alok', place: 'berhampur'}
];

for( var i=myArray.length - 1; i>=0; i--){
        for( var j=0; j<toRemove.length; j++){
            if(myArray[i] && (myArray[i].name === toRemove[j].name)){
                myArray.splice(i, 1);
        }
    }
}

alert(JSON.stringify(myArray));
21
Deepak Acharya

Lodash a également une fonction d’utilité: https://lodash.com/docs#difference

9
Crenshinibon

ECMAScript 6 sets peut être utilisé pour calculer les différents éléments de deux tableaux:

const myArray = new Set(['a', 'b', 'c', 'd', 'e', 'f', 'g']);
const toRemove = new Set(['b', 'c', 'g']);

const difference = new Set([...myArray].filter((x) => !toRemove.has(x)));

console.log(Array.from(difference)); // ["a", "d", "e", "f"]
8
Benny Neugebauer

Je viens de mettre en œuvre en tant que:

Array.prototype.exclude = function(list){
        return this.filter(function(el){return list.indexOf(el)<0;})
}

Utilisé comme:

myArray.exclude(toRemove);
7
user2582833

Si vous ne pouvez pas utiliser de nouvelles fonctions ES5 telles que filter je pense que vous êtes bloqué avec deux boucles:

for( var i =myArray.length - 1; i>=0; i--){
  for( var j=0; j<toRemove.length; j++){
    if(myArray[i] === toRemove[j]){
      myArray.splice(i, 1);
    }
  }
}
6
MarcoL

Maintenant dans la saveur one-liner:

console.log(['a', 'b', 'c', 'd', 'e', 'f', 'g'].filter(x => !~['b', 'c', 'g'].indexOf(x)))

Pourrait ne pas fonctionner sur les anciens navigateurs.

3
Matas Vaitkevicius

Vous pouvez utiliser _. DifferenceBy de lodash

const myArray = [
  {name: 'deepak', place: 'bangalore'}, 
  {name: 'chirag', place: 'bangalore'}, 
  {name: 'alok', place: 'berhampur'}, 
  {name: 'chandan', place: 'mumbai'}
];
const toRemove = [
  {name: 'deepak', place: 'bangalore'},
  {name: 'alok', place: 'berhampur'}
];
const sorted = _.differenceBy(myArray, toRemove, 'name');

Exemple de code ici: CodePen

3
Craciun Ciprian

Que diriez-vous du plus simple possible:

var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
var toRemove = ['b', 'c', 'g'];

var myArray = myArray.filter((item) => !toRemove.includes(item));
console.log(myArray)
2
Eggon
var myArray = [
  {name: 'deepak', place: 'bangalore'}, 
  {name: 'chirag', place: 'bangalore'}, 
  {name: 'alok', place: 'berhampur'}, 
  {name: 'chandan', place: 'mumbai'}`enter code here`
];
var toRemove = [
  {name: 'deepak', place: 'bangalore'},
  {name: 'alok', place: 'berhampur'}
];`enter code here`

        myArray = myArray.filter(ar => !toRemove.find(rm => (rm.name === ar.name && ar.place === rm.place) ))
2
mojtaba roohi

Une façon correcte de supprimer tous les éléments contenus dans un autre tableau consiste à rendre le tableau source même objet en supprimant uniquement les éléments:

Array.prototype.removeContained = function(array) {
  var i, results;
  i = this.length;
  results = [];
  while (i--) {
    if (array.indexOf(this[i]) !== -1) {
      results.Push(this.splice(i, 1));
    }
  }
  return results;
};

Ou équivalent CoffeeScript:

Array.prototype.removeContained = (array) ->
  i = @length
  @splice i, 1 while i-- when array.indexOf(@[i]) isnt -1

Test à l'intérieur de chrome outils de développement:

19: 33: 04.447 a = 1
19: 33: 06.354 b = 2
19: 33: 07.615 c = 3
19: 33: 09.981 arr = [a, b, c]
19: 33: 16.460 arr1 = arr

19: 33: 20.317 arr1 === arr
19: 33: 20.331 vrai

19: 33: 43.592 arr.removeContained ([a, c])
19: 33: 52.433 arr === arr1
19: 33: 52.438 vrai

L'utilisation de la structure Angular constitue le meilleur moyen de conserver le pointeur sur l'objet source lorsque vous mettez à jour des collections sans grande quantité d'observateurs et de rechargements.

0

Je construis la logique sans utiliser de méthodes intégrées, merci de me faire savoir toute optimisation ou modification. J'ai testé dans l'éditeur JS cela fonctionne bien.

var myArray = [
            {name: 'deepak', place: 'bangalore'},
            {name: 'alok', place: 'berhampur'},
            {name: 'chirag', place: 'bangalore'},
            {name: 'chandan', place: 'mumbai'},

        ];
        var toRemove = [

            {name: 'chirag', place: 'bangalore'},
            {name: 'deepak', place: 'bangalore'},
            /*{name: 'chandan', place: 'mumbai'},*/
            /*{name: 'alok', place: 'berhampur'},*/


        ];
        var tempArr = [];
        for( var i=0 ; i < myArray.length; i++){
            for( var j=0; j<toRemove.length; j++){
                var toRemoveObj = toRemove[j];
                if(myArray[i] && (myArray[i].name === toRemove[j].name)) {
                    break;
                }else if(myArray[i] && (myArray[i].name !== toRemove[j].name)){
                        var fnd = isExists(tempArr,myArray[i]);
                        if(!fnd){
                            var idx = getIdex(toRemove,myArray[i])
                            if (idx === -1){
                                tempArr.Push(myArray[i]);
                            }

                        }

                    }

                }
        }
        function isExists(source,item){
            var isFound = false;
            for( var i=0 ; i < source.length; i++){
                var obj = source[i];
                if(item && obj && obj.name === item.name){
                    isFound = true;
                    break;
                }
            }
            return isFound;
        }
        function getIdex(toRemove,item){
            var idex = -1;
            for( var i=0 ; i < toRemove.length; i++){
                var rObj =toRemove[i];
                if(rObj && item && rObj.name === item.name){
                    idex=i;
                    break;
                }
            }
            return idex;
        }
0
Shravan R