2015-01-20 7 views
17

Ich habe dieses Array:Entfernen von Elementen in einem Array mit Lodash

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

Und ich Lodash des remove wie so:

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

Das Ergebnis ist ['Apple', 'Banana', 'Orange', 'Celery'], während ich es erwartet ['Apple', 'Banana', 'Orange'] zu sein. Warum ist das so?

Antwort

47

Denn wenn fruit ist "Celery", Sie testen:

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

die

false || true || true 

die true ist

auswertet.

Sie können diese Syntax nicht verwenden.Entweder tun sie den langen Weg um:

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

oder Test für Array-Mitgliedschaft:

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

Dies ist nicht auf JavaScript beschränkt und ist in der Tat ein häufiger Fehler (zB this question)

+7

Warum nicht '_.includes' anstelle von' _.indexOf' verwenden? –

1

Verwenden Sie ein Array von Werten, mit denen Sie vergleichen möchten, und prüfen Sie, ob ein zurückgegebener Index größer als -1 ist. Dies zeigt an, dass der evaluierte Wert in der Sammlung gefunden wurde.

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

Alternativ können Sie lo-dash's _.contains method verwenden, um eine boolean Antwort zu erhalten.

Das Problem mit der Vorgehensweise, die Sie ergriffen haben, war, dass Sie fruit nicht gegen jede dieser Zeichenfolgen verglichen haben; stattdessen war der einzige Vergleich, der stattfand, fruit gegen "Apple", nachdem Sie Strings ganz allein gezwungen hatten.

Nicht leere Strings true (!!"Banana"), und als solche sind truthy zwingen. Daher wird die folgende Bedingung immer Kurzschluss an "Banana" (es sei denn fruit streng gleich "Apple"), Rückkehr true:

return fruit === "Apple" || 'Banana' || "Orange"; 
+0

Hinweis: Lodash verwendet nicht mehr die Funktion '' _.contains''. Es war ein Alias ​​für '_.includes'', ist aber nicht mehr ab 3.10.0. Verwenden Sie stattdessen "_.includes". https://github.com/mgto/restangular/issues/1298 –

7

Das Problem ist nicht mit Lo-Dash; Ihr Problem ist mit Ihrer Bedingung innerhalb Ihrer Callback-Funktion. Dies:

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

Ist nicht korrekt. Sie müssen tatsächlich fruit mit jeder Saite vergleichen:

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

Oder, können Sie eine andere Lo-Dash-Funktion verwenden, um sie kompakter etwas zu machen:

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

Hinweis: In der neueste Versionen von Lo-Dash die _.contains Funktion ist veraltet. Bitte verwenden Sie _.includes

23

Sie können die Methode _.pull von lodash 2.0 verwenden und bis

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>

5

Wenn Sie einen Satz von Elementen aus einem anderen Satz entfernen möchten, gibt es spezielle Operationen, die speziell dafür vorgesehen sind. Lodash hat https://lodash.com/docs/4.17.2#difference die zwei Array-Parameter A und B erfolgt und wird ein weiteres Array zurück, das alle Elemente von A enthält, die

In Ihrem Fall nicht in B. sind Sie

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

schreiben könnte, wird Ergebnis in ['Celery'].

Verwandte Themen