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?
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 ) );
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]);
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));
Lodash a également une fonction d’utilité: https://lodash.com/docs#difference
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"]
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);
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);
}
}
}
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.
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
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)
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) ))
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 = arr19: 33: 20.317 arr1 === arr
19: 33: 20.331 vrai19: 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.
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;
}