Làm thế nào tôi có thể loại bỏ một yếu tố khỏi danh sách, với lodash?


165

Tôi có một đối tượng trông như thế này:

var obj = {
    "objectiveDetailId": 285,
    "objectiveId": 29,
    "number": 1,
    "text": "x",
    "subTopics": [{
        "subTopicId": 1,
        "number": 1
    }, {
        "subTopicId": 2,
        "number": 32
    }, {
        "subTopicId": 3,
        "number": 22
    }]
}
var stToDelete = 2;

Tôi đã lodashcài đặt trong ứng dụng của tôi cho những thứ khác. Có một cách hiệu quả để sử dụng lodashđể xóa mục: {"subTopicId":2, "number":32}khỏi objđối tượng?

Hoặc có một cách javascript để làm điều này?


1
bạn chỉ có thể sử dụng splice( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
mẹo

1
Thay đổi tiêu đề vì loại bỏ 4 khỏi một mảng [1,4,5] không thể được thực hiện theo cách này. Vâng, tôi hiểu rằng các mảng có thể được thực hiện từ hàm băm / đối tượng và có thể là vậy, nhưng có một sự khác biệt tinh tế trong hai mảng này. Để xóa khỏi một mảng bạn sẽ sử dụng result = _.pull(arr, value) Điều này sẽ xóa tất cả các giá trị khớp khỏi danh sách.
thuyền viên

Câu trả lời:


247

Như lyyons đã chỉ ra trong các bình luận, cách thức thành ngữ và lodashy hơn để làm điều này sẽ được sử dụng _.remove, như thế này

_.remove(obj.subTopics, {
    subTopicId: stToDelete
});

Ngoài ra, bạn có thể chuyển một hàm vị ngữ có kết quả sẽ được sử dụng để xác định xem phần tử hiện tại có phải được loại bỏ hay không.

_.remove(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId === stToDelete;
});

Ngoài ra, bạn có thể tạo một mảng mới bằng cách lọc mảng cũ _.filtervà gán nó cho cùng một đối tượng, như thế này

obj.subTopics = _.filter(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId !== stToDelete;
});

Hoặc là

obj.subTopics = _.filter(obj.subTopics, {subTopicId: stToKeep});

3
Lý do mà câu trả lời này là vì bạn có thể sử dụng hàm vị ngữ , đó chính xác là những gì tôi đang tìm kiếm. Xóa một phần tử là chuyện nhỏ nếu bạn biết chỉ mục, nhưng khi bạn không biết chỉ mục thì sao?
Random_user_name

3
Có thể đáng để đề cập đến _.filter nếu bạn không muốn thay đổi mảng ban đầu ....
Random_user_name

@cale_b Cảm ơn bạn :-) Đã cập nhật câu trả lời với _.filterphiên bản.
thefourtheye

7
@thefourtheye _.filter trả về một phần tử nếu vị ngữ là đúng. Việc triển khai của bạn sẽ trả về tất cả các yếu tố không mong muốn thay vì những yếu tố bạn muốn giữ
Xeltor

5
@thefourtheye bạn nên sử dụng _.rejectthay vì _.filtersử dụng cùng một vị ngữ. Kiểm tra câu trả lời của tôi để biết thêm chi tiết!
Xeltor

29

Chỉ cần sử dụng vanilla JS. Bạn có thể sử dụng spliceđể loại bỏ phần tử:

obj.subTopics.splice(1, 1);

Bản giới thiệu


3
người dùng hỏiIs there an efficient way to use _lodash to delete
semirturgay

7
@Andy Bạn nói đúng, nhưng nếu chỉ số chưa được biết thì sao?
thefourtheye 5/03/2015

3
splice () là cách tiếp cận tốt nhất nếu bạn muốn mảng của mình bị đột biến. Nếu bạn sử dụng remove thì nó trả về mảng mới và điều này phải được gán lại.
omarjebari

Nếu bạn muốn xóa một mục khỏi một mảng bằng chỉ mục của nó trong mảng (rõ ràng, bạn có chỉ mục này nếu bạn muốn thực hiện hành động gỡ bỏ theo cách này), thì sử dụng phương pháp mối nối là cách hiệu quả nhất (và dễ dàng) để làm điều đó. Không cần so sánh bất cứ điều gì và làm cho mã trở nên phức tạp hơn và dễ bị lỗi và lỗi ...
TheCuBeMan

26

bạn có thể làm điều đó với _pull.

_.pull(obj["subTopics"] , {"subTopicId":2, "number":32});

kiểm tra tài liệu tham khảo


7
Theo các tài liệu, _.pullsử dụng bình đẳng nghiêm ngặt để so sánh, tức là === . Hai đối tượng đơn giản khác nhau sẽ không bao giờ so sánh bằng nhau ===(hoặc bởi ==vấn đề đó). Do đó, mã của bạn ở trên sẽ không bao giờ loại bỏ bất kỳ yếu tố nào khỏi mảng.
Đánh dấu Amery

1
Tuy nhiên, đó là người duy nhất làm việc với các chuỗi trong mảng. _.removechỉ cần xóa các mảng.
Yauheni Prakopchyk

3
Tôi vẫn nghĩ rằng đây là câu trả lời đúng. JS .filter loại bỏ tất cả các phần tử khớp, JS .splice yêu cầu tôi biết chỉ mục, _.remove lặp lại trên tất cả các phần tử của mảng do đó kém hiệu quả hơn. _.pull chính xác là những gì tôi muốn: _.pull (mảng, itemToRemove).
Giu-đa Gabriel Himango

21

Bây giờ bạn có thể sử dụng _.reject cho phép bạn lọc dựa trên những gì bạn cần loại bỏ, thay vì những gì bạn cần giữ.

Không giống _.pullhoặc _.removechỉ hoạt động trên mảng, ._rejectđang làm việc trên bất kỳ Collection

obj.subTopics = _.reject(obj.subTopics, (o) => {
  return o.number >= 32;
});

2

Có bốn cách để làm điều này theo tôi biết

const array = [{id:1,name:'Jim'},{id:2,name:'Parker'}];
const toDelete = 1;

Thứ nhất:

_.reject(array, {id:toDelete})

Cái thứ hai là:

_.remove(array, {id:toDelete})

Theo cách này, mảng sẽ bị đột biến.

Cái thứ ba là:

_.differenceBy(array,[{id:toDelete}],'id')
// If you can get remove item 
// _.differenceWith(array,[removeItem])

Cái cuối cùng là:

_.filter(array,({id})=>id!==toDelete)

tôi đang học lodash

Trả lời để làm một bản ghi, để tôi có thể tìm thấy nó sau này.


Tôi đang tìm kiếmreject
Sampgun

2

Ngoài câu trả lời @thefourtheye, sử dụng vị ngữ thay vì các hàm ẩn danh truyền thống:

  _.remove(obj.subTopics, (currentObject) => {
        return currentObject.subTopicId === stToDelete;
    });

HOẶC LÀ

obj.subTopics = _.filter(obj.subTopics, (currentObject) => {
    return currentObject.subTopicId !== stToDelete;
});

1

lodash và bản đánh máy

const clearSubTopics = _.filter(obj.subTopics, topic => (!_.isEqual(topic.subTopicId, 2)));
console.log(clearSubTopics);

0

Đây là hàm lodash đơn giản với mảng và xóa nó bằng số chỉ mục.

index_tobe_delete = 1

fruit = [{a: "apple"}, {b: "banana"}, {c: "choco"}]
_.filter(fruit, (value, key)=> {
return (key !== index_tobe_delete)
})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.