2015-01-20 20 views
17

Tôi có mảng này:yếu tố loại bỏ trong một mảng sử dụng Lodash

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

Và tôi sử dụng remove Lodash của như vậy:

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

Kết quả là ['Apple', 'Banana', 'Orange', 'Celery'], trong khi tôi mong đợi nó được ['Apple', 'Banana', 'Orange']. Tại sao cái này rất?

Trả lời

47

Bởi vì khi fruit"Celery", bạn đang thử nghiệm:

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

mà đánh giá để

false || true || true 

đó là true.

Bạn không thể sử dụng cú pháp đó.Hoặc làm điều đó một chặng đường dài xung quanh:

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

hoặc kiểm tra cho thành viên mảng:

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

này không giới hạn JavaScript, và trên thực tế là một lỗi phổ biến (ví dụ this question)

+7

Tại sao không sử dụng '_.includes' thay vì' _.indexOf'? –

1

Sử dụng một mảng giá trị bạn muốn so sánh và kiểm tra chỉ mục được trả về lớn hơn -1. Điều này cho biết giá trị được đánh giá đã được tìm thấy trong bộ sưu tập.

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

Hoặc bạn có thể sử dụng lo-dash's _.contains method để nhận phản hồi logic.

Sự cố với cách tiếp cận bạn đã thực hiện là bạn không so sánh fruit với từng chuỗi đó; thay vào đó, việc so sánh duy nhất diễn ra là fruit đối với "Apple", sau đó bạn đã tự xâu chuỗi tất cả các chuỗi.

Chuỗi không trống coerce thành true (!!"Banana") và như vậy là truthy. Do đó, các điều kiện sau đây sẽ luôn luôn ngắn mạch tại "Banana" (trừ khi fruit đúng bằng "Apple"), trở về true:

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

Lưu ý: Lodash không còn sử dụng hàm '' _.contains'' nữa. Nó từng là một bí danh cho '' _.includes'', nhưng không còn là 3.10.0 nữa. Sử dụng '' _.includes'' để thay thế. https://github.com/mgonto/restangular/issues/1298 –

7

Vấn đề không phải là với Lo-Dash; vấn đề của bạn là với điều kiện của bạn trong hàm gọi lại của bạn. Đây:

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

không đúng. Bạn cần phải thực sự so sánh fruit với mỗi chuỗi:

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

Hoặc, bạn có thể sử dụng một chức năng Lo-Dash để làm cho nó nhỏ gọn hơn một chút:

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

Lưu ý: Trong các phiên bản mới nhất của Lo-Dash, chức năng _.contains không được chấp nhận. Vui lòng sử dụng _.includes

23

Bạn có thể sử dụng phương thức _.pull từ lodash 2.0 và lên

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

Nếu bạn muốn xóa một tập hợp các mục khỏi nhóm khác, có các hoạt động được thiết lập dành riêng cho điều đó. Lodash có https://lodash.com/docs/4.17.2#difference đó có hai tham số mảng A và B và sẽ trở lại một mảng mà chứa tất cả các phần tử của A mà không thuộc B.

Trong trường hợp của bạn, bạn có thể viết

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

mà sẽ kết quả là ['Celery'].

Các vấn đề liên quan