I have this array:
var fruits = ['Apple', 'Banana', 'Orange', 'Celery'];
And I use Lodash's remove
like so:
_.remove(fruits, function (fruit) {
return fruit === 'Apple' || 'Banana' || 'Orange';
})
The result is ['Apple', 'Banana', 'Orange', 'Celery']
, while I expected it to be ['Apple', 'Banana', 'Orange']
. Why is this so?
Because when fruit
is "Celery"
, you are testing:
"Celery" === 'Apple' || 'Banana' || 'Orange'
which evaluates to
false || true || true
which is true
.
You can't use that syntax. Either do it the long way around:
_.remove(fruits, function (fruit) {
return fruit === 'Apple' || fruit === 'Banana' || fruit === 'Orange'
});
or test for array membership:
_.remove(fruits, function (fruit) {
return _.indexOf(['Apple', 'Banana', 'Orange'], fruit) !== -1
});
This is not limited to JavaScript, and is in fact a common mistake (eg this question )
You can use the method _.pull
from lodash 2.0 and up
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>
The problem isn't with Lo-Dash; your problem is with your conditional within your callback function. This:
return fruit === 'Apple' || 'Banana' || 'Orange';
Is not correct. You need to actually compare fruit
with each string:
return fruit === 'Apple' || fruit === 'Banana' || fruit === 'Orange';
Or , you can use another Lo-Dash function to make it a little more compact:
_.remove(fruits, function (fruit) {
return _.contains(['Apple', 'Banana', 'Orange'], fruit);
})
Note: In the latest versions of Lo-Dash the _.contains
function is deprecated. Please use _.includes
If you want to remove a set of items from another set, there are set operations intended specifically for that. Lodash has https://lodash.com/docs/4.17.2#difference which takes two array parameters A and B and will return another array which contains all of the elements of A which are not in B.
In your case, you could write
const fruits = ['Apple', 'Banana', 'Orange', 'Celery'];
const filteredFruits = _.difference(fruits, ['Apple', 'Banana', 'Orange']);
which will result in ['Celery']
.
Use an array of values that you'd like to compare against, and check for a returned index greater than -1. This indicates the value evaluated was found in the collection.
_.remove( fruits, function ( fruit ) {
return _.indexOf( [ "Apple", "Banana", "Orange" ], fruit ) >= 0;
});
Alternatively you could use lo-dash's _.contains
method to get a boolean response.
The problem with the approach you took was that you weren't comparing fruit
against each one of those strings; instead, the only comparison taking place was fruit
against "Apple"
, after that you were coercing strings all on their own.
Non-empty strings coerce to true
( !!"Banana"
), and as such are truthy . Therefore, the following condition will always short-circuit at "Banana" (unless fruit
strictly equals "Apple"
), returning true
:
return fruit === "Apple" || 'Banana' || "Orange";
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.