2015-01-20 13 views
17

ho questa matrice:Rimozione di elementi di un array utilizzando Lodash

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

e io uso remove di Lodash in questo modo:

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

Il risultato è ['Apple', 'Banana', 'Orange', 'Celery'], mentre mi aspettavo che fosse ['Apple', 'Banana', 'Orange']. Perché è così?

risposta

47

Perché quando fruit è "Celery", si sta testando:

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

che restituisce

false || true || true 

che è true.

Non è possibile utilizzare questa sintassi.O lo fanno un lungo giro:

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

o il test per l'adesione matrice:

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

Questo non è limitato a JavaScript, ed è in realtà un errore comune (ad es this question)

+7

Perché non utilizzare '_.includes' invece di' _.indexOf'? –

1

Utilizzare una matrice di valori che si desidera confrontare e verificare un indice restituito maggiore di -1. Questo indica che il valore valutato è stato trovato nella collezione.

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

In alternativa si potrebbe utilizzare lo-dash's _.contains method per ottenere una risposta booleana.

Il problema con l'approccio che hai preso era che non stavi confrontando fruit contro ciascuna di quelle stringhe; invece, l'unico paragone in corso è stato fruit contro "Apple", dopo di che si stavano forzando le corde da sole.

stringhe non vuote costringono a true (!!"Banana"), e come tali sono truthy. Pertanto, la seguente condizione sarà sempre cortocircuito "banana" (a meno fruit uguale strettamente "Apple"), tornando true:

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

Nota: Lodash non utilizza più la funzione '' _.contains''. Era un alias per '' _.includes'', ma non è più il 3.10.0. Usa invece '' _.includes''. https://github.com/mgonto/restangular/issues/1298 –

7

Il problema non è con Lo-Dash; il tuo problema è con il tuo condizionale all'interno della tua funzione di callback. Questo:

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

È non corretta. È necessario confrontare realmente fruit con ogni stringa:

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

O, è possibile utilizzare un'altra funzione Lo-Dash per renderlo un po 'più compatta:

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

Nota: Nel le ultime versioni di Lo-Dash la funzione _.contains sono obsolete. Si prega di utilizzare _.includes

23

È possibile utilizzare il metodo _.pull da lodash 2.0 e fino

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

Se si desidera rimuovere un set di elementi da un altro set, sono state impostate operazioni specifiche per tale scopo. Lodash ha https://lodash.com/docs/4.17.2#difference che richiede due parametri array A e B e tornerà un altro array che contiene tutti gli elementi di A che non sono in B.

Nel tuo caso, si potrebbe scrivere

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

che sarà risultato in ['Celery'].

Problemi correlati