javascript mencari dan menghapus objek dalam array berdasarkan nilai kunci


145

Saya telah mencoba beberapa pendekatan tentang cara menemukan objek dalam array, di mana ID = var, dan jika ditemukan, hapus objek dari array dan kembalikan objek array baru.

Data:

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

Saya dapat mencari array menggunakan jQuery $ grep;

var id = 88;

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

Tetapi bagaimana saya bisa menghapus seluruh objek ketika id == 88, dan mengembalikan data seperti ini:

Data:

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

Bagaimana dengan menggunakan slicefungsi dan sedikit forputaran?
Ahmed Hamdy

1
Tentu, tetapi, alasan saya menulis pertanyaan ini, adalah karena saya terjebak;) ada potongan?
Tom


Judul dan teks pertanyaan tampaknya bertentangan ... menyarankan dua pendekatan yang sama sekali berbeda: A. menghapus item dari larik versus B. membuat larik baru yang difilter.
kanon

Jawaban:


157

Saya bisa grep array untuk id, tapi bagaimana saya bisa menghapus seluruh objek di mana id == 88

Cukup filter dengan predikat sebaliknya:

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

13
Jawaban ini memberikan solusi paling ringkas dan idiomatis untuk jQuery
Bryan

1
Dalam kasus Anda di mana Anda ingin menghapus semua item dengan id = sesuatu baik-baik saja ... tapi hati-hati saat menggunakan $ .grep karena mencari array penuh dan untuk array yang panjang itu tidak efisien. Terkadang Anda hanya perlu memeriksa apakah elemen tersebut ada di dalam array dengan ID yang diberikan, maka lebih baik menggunakan metode iterasi lain;)
julianox

1
Ini tidak menghapus objek itu dari daftar
Arun Sivan

1
@ArunSivan slicejuga tidak menghapus apa pun. Tidak yakin apa yang Anda maksud. Jika Anda sendiri memiliki masalah tertentu, Anda mungkin ingin mengajukan pertanyaan baru .
Bergi

1
@Learnerdata.filter(e => !ids.includes(e.id))
Bergi

166

berikut adalah solusi jika Anda tidak menggunakan jquery:

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

2
Apakah ini lebih baik daripada melakukan findIndex()dan kemudian splice(index, 1)pada array induk?
Alex

sambatan memutasikan larik asal. Dengan filter Anda punya pilihan.
velop

14
Anda dapat mengurangi ini menjadi satu baris dengan menggunakan: myArr = myArray.filter (obj => obj.id! == id);
DBrown

3
bahkan lebih ringkasarr = arr.filter( obj => obj.id !== id);
Omar

87

Anda dapat menyederhanakan ini, dan sebenarnya tidak perlu menggunakan jquery di sini.

var id = 88;

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

Cukup lakukan iterasi melalui daftar, temukan id yang cocok, sambungan, lalu putus untuk keluar dari loop Anda


17
+1, tetapi Anda harus menyebutkan bahwa ini hanya menghapus item pertama yang cocok.
Bergi

6
... Dan jika Anda perlu menghapus setiap item yang cocok, putar ulang urutannya dengan i=data.length; i > 0; i--dan jangan gunakan break.
Jeremy Belolo

3
i = data.lengthakan merusak apa pun data[i], itu harus sepertii=data.length -1 ; i > -1; i--
distante

35

Ada metode baru untuk melakukan ini di ES6 / 2015 menggunakan findIndex dan operator spread array:

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

Anda dapat mengubahnya menjadi fungsi untuk digunakan kembali nanti seperti ini:

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;
}

Dengan cara ini Anda bisa menghapus item dengan kunci berbeda menggunakan satu metode (dan jika tidak ada objek yang memenuhi kriteria, Anda mendapatkan kembali larik asli):

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

Atau Anda dapat meletakkannya di Array.prototype Anda:

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;
};

Dan gunakan dengan cara ini:

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

findIndex () benar-benar hebat! 👍
danielcraigie

Bagaimana jika Anda memiliki lebih dari satu kunci dan nilai?
QMaster

9

Dengan asumsi bahwa id itu unik dan Anda hanya perlu menghapus satu elemen splicesaja sudah cukup:

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);

Anda memiliki elemen dalam fungsi panggilan balik Anda. Seharusnya begitu each(data,function(idx,ele). Saya akan menagih Anda nanti untuk 30 menit saya menyia-nyiakan mencari tahu itu :)
CSharper

Ups. Paling tidak yang bisa saya lakukan dalam kasus itu adalah memperbarui jawaban saya. Saya merasa sangat buruk tentang 30 menit hidup Anda yang terbuang.
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!"}
];

Jika Anda menggunakan jQuery, gunakan jQuery.grep seperti ini:

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

Menggunakan ES5 Array.prototype.filter :

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

1
Tidaaaaaaak! Jangan gunakan jQuerypeta sebagai filter.
Bergi

1
Setuju! Solusi Anda dengan grep adalah solusi yang tepat dengan jQuery.
nekman

4

Mungkin Anda sedang mencari $.grep()fungsi:

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

siftadalah filter koleksi yang andal untuk operasi seperti ini dan yang lebih canggih. Ia bekerja di sisi klien di browser atau sisi server di 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);

Mendukung filter seperti $in, $nin, $exists, $gte, $gt, $lte, $lt, $eq, $ne, $mod, $all, $and, $or, $nor, $not, $size, $type, dan $regex, dan berusaha untuk menjadi API-kompatibel dengan koleksi MongoDB penyaringan.


Mengapa tidak ada upwote? Jika hal ini ditulis dengan benar dan tidak memiliki bug yang buruk, itu akan sangat berguna.
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;
}

Ini seharusnya berhasil, jsfiddle


0

Pastikan Anda memaksa id objek menjadi integer jika Anda menguji kesetaraan yang ketat:

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

Demo


0

Jika Anda menggunakan js garis bawah, mudah untuk menghapus objek berdasarkan kunci. http://underscorejs.org . Contoh:

  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];
  });

0

A setuju dengan jawaban, cara sederhana jika Anda ingin mencari dan menolak id dan menghapusnya adalah seperti kode di bawah ini.

   var obj = JSON.parse(data);
   var newObj = obj.filter(item=>item.Id!=88);
       
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.