javascript tìm và xóa đối tượng trong mảng dựa trên giá trị khóa


138

Tôi đã thử một vài cách tiếp cận về cách tìm một đối tượng trong một mảng, trong đó ID = var và nếu tìm thấy, hãy xóa đối tượng khỏi mảng và trả về mảng đối tượng mới.

Dữ liệu:

[
    {"id":"88","name":"Lets go testing"},
    {"id":"99","name":"Have fun boys and girls"},
    {"id":"108","name":"You are awesome!"}
]

Tôi có thể tìm kiếm mảng bằng jQuery $ grep;

var id = 88;

var result = $.grep(data, function(e){ 
     return e.id == id; 
});

Nhưng làm cách nào tôi có thể xóa toàn bộ đối tượng khi id == 88 và trả về dữ liệu như thế này:

Dữ liệu:

[
    {"id":"99","name":"Have fun boys and girls"},
    {"id":"108","name":"You are awesome!"}
]

Điều gì về việc sử dụng slicechức năng và một forvòng lặp nhỏ ?
Ahmed Hamdy

1
Chắc chắn, nhưng, lý do tôi viết câu hỏi này, là bởi vì tôi bị mắc kẹt;) bất kỳ đoạn trích nào?
Tom

Kiểm tra bài đăng này stackoverflow.com/questions/10827894/
Kẻ

Tiêu đề và văn bản câu hỏi dường như mâu thuẫn ... gợi ý hai cách tiếp cận hoàn toàn khác nhau: A. xóa các mục khỏi một mảng so với B. tạo một mảng mới, được lọc.
canon

Câu trả lời:


155

Tôi có thể grep mảng cho id, nhưng làm cách nào tôi có thể xóa toàn bộ đối tượng trong đó id == 88

Đơn giản chỉ cần lọc theo vị ngữ ngược lại:

var data = $.grep(data, function(e){ 
     return e.id != id; 
});

12
Câu trả lời này cung cấp giải pháp ngắn gọn và thành ngữ nhất cho jQuery
Bryan

1
Trong trường hợp bạn muốn xóa tất cả các mục bằng id = một cái gì đó tốt ... nhưng hãy cẩn thận khi sử dụng $ .grep vì nó tìm kiếm toàn bộ mảng và đối với các mảng dài thì không hiệu quả. Đôi khi bạn chỉ cần kiểm tra xem phần tử có tồn tại bên trong mảng bằng một ID đã cho hay không, tốt hơn là sử dụng phương pháp lặp khác;)
julianox

1
Điều này không xóa đối tượng đó khỏi danh sách
Arun Sivan

1
@ArunSivan slicecũng không xóa bất cứ thứ gì. Không chắc chắn những gì bạn đang nhận được. Nếu bạn có một vấn đề cụ thể, bạn có thể muốn hỏi một câu hỏi mới .
Bergi

1
@ Học viêndata.filter(e => !ids.includes(e.id))
Bergi

150

Đây là một giải pháp nếu bạn không sử dụng jquery:

myArray = myArray.filter(function( obj ) {
  return obj.id !== id;
});

2
Điều này có tốt hơn làm findIndex()và sau đó splice(index, 1)trên mảng cha?
Alex

mối nối đột biến mảng khởi tạo. Với bộ lọc bạn có sự lựa chọn.
velop

13
Bạn có thể giảm dòng này xuống một dòng bằng cách sử dụng: myArr = myArray.filter (obj => obj.id! == id);
DBrown

2
thậm chí ngắn gọn hơnarr = arr.filter( obj => obj.id !== id);
Omar

86

Bạn có thể đơn giản hóa điều này và thực sự không cần sử dụng jquery ở đây.

var id = 88;

for(var i = 0; i < data.length; i++) {
    if(data[i].id == id) {
        data.splice(i, 1);
        break;
    }
}

Chỉ cần lặp qua danh sách, tìm id phù hợp, mối nối và sau đó ngắt để thoát khỏi vòng lặp của bạn


17
+1, nhưng bạn nên đề cập rằng điều này chỉ xóa mục đầu tiên phù hợp.
Bergi

6
... Và nếu bạn cần xóa từng mục phù hợp, hãy lặp lại theo thứ tự ngược lại i=data.length; i > 0; i--và không sử dụng break.
Jeremy Belolo

3
i = data.lengthsẽ phá vỡ bất kỳ data[i], nó sẽ giống nhưi=data.length -1 ; i > -1; i--
distante

31

Có một phương pháp mới để thực hiện điều này trong ES6 / 2015 bằng cách sử dụng toán tử find Index và toán tử trải rộng mảng:

const index = data.findIndex(obj => obj.id === id);
const newData = [
    ...data.slice(0, index),
    ...data.slice(index + 1)
]

Bạn có thể biến nó thành một chức năng để sử dụng lại sau này như sau:

function remove(array, key, value) {
    const index = array.findIndex(obj => obj[key] === value);
    return index >= 0 ? [
        ...array.slice(0, index),
        ...array.slice(index + 1)
    ] : array;
}

Bằng cách này, bạn có thể xóa các mục bằng các khóa khác nhau bằng một phương thức (và nếu không có đối tượng nào đáp ứng tiêu chí, bạn sẽ nhận được mảng ban đầu được trả về):

const newData = remove(data, "id", "88");
const newData2 = remove(data, "name", "You are awesome!");

Hoặc bạn có thể đặt nó trên Array.prototype của bạn:

Array.prototype.remove = function (key, value) {
    const index = this.findIndex(obj => obj[key] === value);
    return index >= 0 ? [
        ...this.slice(0, index),
        ...this.slice(index + 1)
    ] : this;
};

Và sử dụng nó theo cách này:

const newData = data.remove("id", "88");
const newData2 = data.remove("name", "You are awesome!");

find Index () thực sự tuyệt vời! 👍
danielcraigie

9

Giả sử rằng id là duy nhất và bạn sẽ chỉ phải xóa một yếu tố splicenên thực hiện thủ thuật:

var data = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
],
id = 88;

console.table(data);

$.each(data, function(i, el){
  if (this.id == id){
    data.splice(i, 1);
  }
});

console.table(data);

Bạn có các yếu tố trong chức năng gọi lại của bạn ngược. Nó phải each(data,function(idx,ele). Tôi sẽ gửi hóa đơn cho bạn sau 30 phút tôi đã lãng phí khi tìm ra điều đó :)
CSharper

Giáo sư. Ít nhất tôi có thể làm trong trường hợp đó là cập nhật câu trả lời của tôi. Tôi cảm thấy thực sự tồi tệ về 30 phút lãng phí của cuộc đời bạn.
James Hibbard

5
var items = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
];

Nếu bạn đang sử dụng jQuery, hãy sử dụng jQuery.grep như thế này:

items = $.grep(items, function(item) { 
  return item.id !== '88';
});
// items => [{ id: "99" }, { id: "108" }]

Sử dụng ES5 Array.prototype.filter :

items = items.filter(function(item) { 
  return item.id !== '88'; 
});
// items => [{ id: "99" }, { id: "108" }]

1
Không! Không sử dụng jQuerybản đồ làm bộ lọc.
Bergi

1
Đồng ý! Giải pháp của bạn với grep là giải pháp phù hợp với jQuery.
nekman

4

Có thể bạn đang tìm kiếm $.grep()chức năng:

arr = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
];

id = 88;
arr = $.grep(arr, function(data, index) {
   return data.id != id
});

3

siftlà một bộ lọc bộ sưu tập mạnh mẽ cho các hoạt động như thế này và những bộ nâng cao hơn nhiều. Nó hoạt động phía máy khách trong trình duyệt hoặc phía máy chủ trong node.js.

var collection = [
    {"id":"88","name":"Lets go testing"},
    {"id":"99","name":"Have fun boys and girls"},
    {"id":"108","name":"You are awesome!"}
];
var sifted = sift({id: {$not: 88}}, collection);

Nó hỗ trợ các bộ lọc như $in, $nin, $exists, $gte, $gt, $lte, $lt, $eq, $ne, $mod, $all, $and, $or, $nor, $not, $size, $type, và $regex, và phấn đấu để được API tương thích với bộ lọc bộ sưu tập MongoDB.


Tại sao không có upwote? Nếu điều này được viết đúng và không có lỗi khủng khiếp thì nó sẽ rất hữu ích.
Max Yari

2
Array.prototype.removeAt = function(id) {
    for (var item in this) {
        if (this[item].id == id) {
            this.splice(item, 1);
            return true;
        }
    }
    return false;
}

Điều này nên làm thủ thuật, jsfiddle


0

Hãy chắc chắn rằng bạn ép buộc id đối tượng thành một số nguyên nếu bạn kiểm tra sự bằng nhau nghiêm ngặt:

var result = $.grep(data, function(e, i) { 
  return +e.id !== id;
});

Bản giới thiệu


0

Nếu bạn đang sử dụng js gạch dưới, có thể dễ dàng xóa đối tượng dựa trên khóa. http://underscorejs.org . Thí dụ:

  var temp1=[{id:1,name:"safeer"},  //temp array
             {id:2,name:"jon"},
             {id:3,name:"James"},
             {id:4,name:"deepak"},
             {id:5,name:"ajmal"}];

  var id = _.pluck(temp1,'id'); //get id array from temp1
  var ids=[2,5,10];             //ids to be removed
  var bool_ids=[];
  _.each(ids,function(val){
     bool_ids[val]=true;
  });
  _.filter(temp1,function(val){
     return !bool_ids[val.id];
  });
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.