Xóa một mục khỏi mảng bằng UnderscoreJS


137

Nói rằng tôi có mã này

var Array = [{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 3, name: 'c'}];

và tôi muốn xóa mục có id = 3 khỏi mảng. Có cách nào để làm điều này mà không cần nối? Có thể một cái gì đó bằng cách sử dụng gạch dưới hoặc một cái gì đó như thế?

Cảm ơn!


Nếu bạn không muốn tạo một mảng mới, nối là lựa chọn duy nhất. Tôi cá là gạch dưới cũng sử dụng nó (bên trong, nếu phương thức đó tồn tại).
Felix Kling

6
Có gì sai với nối?
Vidime Vidas

Bạn đã kiểm tra tham chiếu của gạch dưới chưa?
Vidime Vidas

Chỉ cần sử dụng JavaScript đơn giản, đây là một bản sao của việc loại bỏ các đối tượng khỏi mảng bởi thuộc tính đối tượng .
Felix Kling

5
cũng không bị trùng lặp vì nó có thẻ cho underscore.js
Garis M Suero

Câu trả lời:


279

Chỉ cần sử dụng JavaScript đơn giản, điều này đã được trả lời: xóa các đối tượng khỏi mảng bởi thuộc tính đối tượng .

Sử dụng underscore.js, bạn có thể kết hợp .findWherevới .without:

var arr = [{
  id: 1,
  name: 'a'
}, {
  id: 2,
  name: 'b'
}, {
  id: 3,
  name: 'c'
}];

//substract third
arr = _.without(arr, _.findWhere(arr, {
  id: 3
}));
console.log(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

Mặc dù, vì dù sao bạn cũng đang tạo một mảng mới trong trường hợp này, bạn chỉ có thể sử dụng _.filterhoặc Array.prototype.filterhàm gốc (giống như được hiển thị trong câu hỏi khác). Sau đó, bạn sẽ chỉ lặp lại trên mảng một lần thay vì có khả năng hai lần như ở đây.

Nếu bạn muốn sửa đổi mảng tại chỗ , bạn phải sử dụng .splice. Điều này cũng được thể hiện trong câu hỏi khác và undescore dường như không cung cấp bất kỳ chức năng hữu ích nào cho việc đó.


1
Đúng, nó hoạt động hoàn hảo, tôi đã xem qua tài liệu gạch dưới nhưng không hiểu làm thế nào để lấy nó ra mà không có. Cảm ơn bạn!
leo núi

10
Sẽ không _.reject hay _.filter () hiệu quả hơn ở đây? Bạn sẽ kết thúc với hai lần lặp lại danh sách chỉ để lấy ra một mục.
Rick Strahl

1
Đây có thể là một bản sao nhưng đây là câu trả lời tốt hơn.
Michael J. Calkins

2
@RickStrahl Bạn nói đúng. _.rejectCó vẻ như một lựa chọn tốt hơn ở đây.
Tarik

1
@lukaserat để bật phần tử cuối cùng, sử dụng arr.pop()...
Emile Bergeron

96

Bạn có thể sử dụng gạch dưới .filter

    var arr = [{
      id: 1,
      name: 'a'
    }, {
      id: 2,
      name: 'b'
    }, {
      id: 3,
      name: 'c'
    }];

    var filtered = _(arr).filter(function(item) {
         return item.id !== 3
    });

Cũng có thể được viết là:

var filtered = arr.filter(function(item) {
    return item.id !== 3
});

var filtered = _.filter(arr, function(item) {
    return item.id !== 3
});

Kiểm tra Fiddle

Bạn cũng có thể dùng .reject


Tôi nghĩ bạn có nghĩa là: var được lọc = _.filter (mảng, hàm (mục) {return item.id! == 3});
tbh__

2
@tbh__ _()sẽ tạo một trình bao bọc xung quanh bộ sưu tập cho phép bạn gọi các phương thức gạch dưới.
Sushanth -

Đã sử dụng gạch dưới trong nhiều năm, tôi không bao giờ biết điều này. Cảm ơn
tbh__


16

Underscore có phương thức _without () hoàn hảo để xóa một mục khỏi một mảng, đặc biệt nếu bạn có đối tượng cần xóa.

Trả về một bản sao của mảng với tất cả các phiên bản của các giá trị bị xóa.

_.without(["bob", "sam", "fred"], "sam");

=> ["bob", "fred"]

Hoạt động với các đối tượng phức tạp hơn quá.

var bob = { Name: "Bob", Age: 35 };
var sam = { Name: "Sam", Age: 19 };
var fred = { Name: "Fred", Age: 50 };

var people = [bob, sam, fred]

_.without(people, sam);

=> [{ Name: "Bob", Age: 35 }, { Name: "Fred", Age: 50 }];

Nếu bạn không có mục nào để xóa, chỉ cần một thuộc tính của nó, bạn có thể sử dụng _.findWherevà sau đó _.without.


2
Lưu ý: điều này chỉ hoạt động vì bạn chuyển đối tượng sam sang mà không có. Thay vào đó, nếu bạn chuyển { Name: "Sam", Age: 19 }sang không có, thay vì biến sam, nó không còn hoạt động. Fiddle
Adam

5

Vui lòng thực hiện cẩn thận nếu bạn đang lọc các chuỗi và tìm kiếm các bộ lọc không phân biệt chữ hoa chữ thường. _.without () là trường hợp nhạy cảm. Bạn cũng có thể sử dụng _.reject () như hiển thị bên dưới.

var arr = ["test","test1","test2"];

var filtered = _.filter(arr, function(arrItem) {
    return arrItem.toLowerCase() !== "TEST".toLowerCase();
});
console.log(filtered);
// ["test1", "test2"]

var filtered1 = _.without(arr,"TEST");
console.log(filtered1);
// ["test", "test1", "test2"]

var filtered2 = _.reject(arr, function(arrItem){ 
    return arrItem.toLowerCase() === "TEST".toLowerCase();
});
console.log(filtered2);
// ["test1", "test2"]

4

Các câu trả lời khác tạo một bản sao mới của mảng, nếu bạn muốn sửa đổi mảng tại chỗ, bạn có thể sử dụng:

arr.splice(_.findIndex(arr, { id: 3 }), 1);

Nhưng điều đó giả định rằng phần tử sẽ luôn được tìm thấy bên trong mảng (vì nếu không tìm thấy nó vẫn sẽ loại bỏ phần tử cuối cùng). Để an toàn bạn có thể sử dụng:

var index = _.findIndex(arr, { id: 3 });
if (index > -1) {
    arr.splice(index, 1);
}

2

hoặc một cách tiện dụng khác:

_.omit(arr, _.findWhere(arr, {id: 3}));

2 xu của tôi


1
bỏ qua hoạt động objectvà trả về một object. do đó không tốt khi làm việc với Arraysnơi mà chúng ta có thể mong đợi để lấy arraylại sau khi loại bỏ một yếu tố.
ScrapCode

1
Vì vậy, _.without là cái bạn đang xem: _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
Nadeem

2

Sử dụng có thể sử dụng đồng bằng JavaScript của Array#filterphương pháp như thế này:

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var filteredArr = arr.filter(obj => obj.id != 3);

console.log(filteredArr);

Hoặc, sử dụng Array#reduceArray#concatphương pháp như thế này:

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var reducedArr = arr.reduce((accumulator, currObj) => {
  return (currObj.id != 3) ? accumulator.concat(currObj) : accumulator;
}, []);

console.log(reducedArr);

GHI CHÚ:

  • Cả hai đều là cách tiếp cận chức năng thuần túy ( nghĩa là chúng không sửa đổi mảng hiện có).
  • Không, thư viện bên ngoài được yêu cầu theo cách tiếp cận này (Vanilla JavaScript là đủ).

0

Tôi đã từng thử phương pháp này

_.filter(data, function(d) { return d.name != 'a' });

Có thể có các phương pháp tốt hơn giống như các giải pháp trên được cung cấp bởi người dùng


0

Bằng cách sử dụng underscore.js

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var resultArr = _.reject(arr,{id:3});

console.log(resultArr);

Kết quả sẽ là :: [{id:1name:'a'},{id:2,name:'c'}]


-1

Bạn có thể sử dụng phương thức từ chối của Underscore, bên dưới sẽ trả về một mảng mới sẽ không có mảng với kết quả khớp cụ thể

arr = _.reject(arr, function(objArr){ return objArr.id == 3; });
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.