web-dev-qa-db-fra.com

Supprimer des éléments dans un tableau avec Lodash

J'ai ce tableau:

var fruits = ['Apple', 'Banana', 'Orange', 'Celery'];

Et j'utilise remove de Lodash comme ceci:

_.remove(fruits, function (fruit) {
  return fruit === 'Apple' || 'Banana' || 'Orange';
})

Le résultat est ['Apple', 'Banana', 'Orange', 'Celery'], alors que je m'attendais à ce que ce soit ['Apple', 'Banana', 'Orange']. Pourquoi cela est-il ainsi?

23
bard

Parce que quand fruit est "Celery", vous testez:

"Celery" === 'Apple' || 'Banana' || 'Orange'

qui évalue à

false || true || true

qui est true.

Vous ne pouvez pas utiliser cette syntaxe. Soit le faire le long chemin autour:

_.remove(fruits, function (fruit) {
  return fruit === 'Apple' || fruit === 'Banana' || fruit === 'Orange'
});

ou test d'adhésion au tableau:

_.remove(fruits, function (fruit) {
  return _.indexOf(['Apple', 'Banana', 'Orange'], fruit) !== -1
});

Ce n'est pas limité à JavaScript, et est en fait une erreur commune (par exemple cette question )

50
Amadan

Vous pouvez utiliser la méthode _.pull à partir de Lodash 2.0 et plus

var fruits = ['Apple', 'Banana', 'Orange', 'Celery'];

_.pull(fruits, 'Apple', 'Banana', 'Orange'); // ['Celery']

document.write(fruits);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.js"></script>
33
gustavogelf

Si vous souhaitez supprimer un ensemble d'éléments d'un autre ensemble, des opérations sur les ensembles sont spécialement conçues pour cela. Lodash a https://lodash.com/docs/4.17.2#difference qui prend deux paramètres de tableau A et B et retournera un autre tableau contenant tous les éléments de A qui ne sont pas dans B .

Dans votre cas, vous pourriez écrire

const fruits = ['Apple', 'Banana', 'Orange', 'Celery'];
const filteredFruits = _.difference(fruits, ['Apple', 'Banana', 'Orange']);

ce qui entraînera ['Celery'].

8
Mouscellaneous

Le problème n'est pas avec Lo-Dash; votre problème est avec votre conditionnel dans votre fonction de rappel. Cette:

return fruit === 'Apple' || 'Banana' || 'Orange';

Est pas correct. Vous devez réellement comparer fruit avec chaque chaîne:

return fruit === 'Apple' || fruit === 'Banana' || fruit === 'Orange';

Ou, vous pouvez utiliser une autre fonction Lo-Dash pour la rendre un peu plus compacte:

_.remove(fruits, function (fruit) {
  return _.contains(['Apple', 'Banana', 'Orange'], fruit);
})

Remarque: Dans les dernières versions de Lo-Dash, le _.contains _ function est obsolète. Veuillez utiliser _.includes

8
ncksllvn

Utilisez un tableau de valeurs que vous souhaitez comparer et recherchez un index renvoyé supérieur à -1. Cela indique que la valeur évaluée a été trouvée dans la collection.

_.remove( fruits, function ( fruit ) {
  return _.indexOf( [ "Apple", "Banana", "Orange" ], fruit ) >= 0;
});

Vous pouvez également utiliser la méthode méthode _.contains De lo-dash pour obtenir une réponse booléenne.

Le problème avec votre approche était que vous ne compariez pas fruit avec chacune de ces chaînes; au lieu de cela, la seule comparaison effectuée était fruit contre "Apple", après quoi vous contraigniez les chaînes elles-mêmes.

Les chaînes non vides forcent true (!!"Banana"), Et en tant que telles sont vérités . Par conséquent, la condition suivante court-circuitera toujours "Banane" (à moins que fruit ne soit strictement égale à "Apple"), Renvoyant true:

return fruit === "Apple" || 'Banana' || "Orange";
2
Sampson