Hapus elemen array berdasarkan properti objek

271

Saya memiliki berbagai objek seperti:

var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];

Bagaimana cara menghapus yang spesifik berdasarkan propertinya?

mis. Bagaimana cara saya menghapus objek array dengan 'uang' sebagai properti bidang?

imperium2335
sumber

Jawaban:

384

Satu kemungkinan:

myArray = myArray.filter(function( obj ) {
    return obj.field !== 'money';
});

Harap perhatikan bahwa filtermembuat array baru. Variabel lain apa pun yang merujuk ke array asli tidak akan mendapatkan data yang difilter meskipun Anda memperbarui variabel asli Anda myArraydengan referensi baru. Gunakan dengan hati-hati.

jandy
sumber
6
Catatan yang filter()hanya tersedia untuk Internet Explorer 9+
jessegavin
@jessegavin memang. Saya seharusnya menyebutkan bahwa ada banyak pustaka ES5 shim bagus yang tersedia, yang meniru fungsionalitas (untuk berjaga-jaga jika Anda ingin mendukung browser lama)
jAndy
3
filter()membuat array baru, yang boleh jika Anda dapat menetapkan kembali variabel dan tahu bahwa tidak ada area kode lain yang memiliki referensi untuk itu. Ini tidak akan berfungsi jika Anda secara khusus perlu memodifikasi objek array asli.
Brian Glick
2
Bagaimana jika array adalah struktur pohon ar sebelumDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "tes yang diubah 23"}]}] dan saya ingin menghapus id: 23
forgottofly
@forgottofly poin bagus - jawaban hanya berfungsi untuk kasus terbatas. Apakah Anda menemukan jawaban untuk pertanyaan Anda?
JackTheKnife
88

Iterasi melalui array, dan splicekeluar yang tidak Anda inginkan. Untuk penggunaan yang lebih mudah, beralihlah ke belakang sehingga Anda tidak harus memperhitungkan sifat langsung dari array:

for (var i = myArray.length - 1; i >= 0; --i) {
    if (myArray[i].field == "money") {
        myArray.splice(i,1);
    }
}
Niet the Dark Absol
sumber
3
apa yang Anda maksud dengan sifat langsung dari array? @Neit the Dark Absol
sisimh
29
@sisimh maksudnya bahwa jika Anda beralih ke depan atas array dengan menggunakan panjangnya sebagai bagian dari logika iterasi dan panjangnya berubah karena elemen dihapus atau ditambahkan, Anda dapat berakhir menjalankan ujung array atau tidak melakukan operasi untuk setiap item dalam array. Mundur membuat itu jauh lebih kecil kemungkinannya karena bekerja menuju indeks 0 statis daripada panjang bergerak.
Klors
2
Bagaimana jika array adalah struktur pohon ar sebelumDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "tes yang diubah 23"}]}] dan saya ingin menghapus id: 23
forgottofly
Agak jelas, tetapi jika Anda hanya berharap untuk menghapus elemen tunggal yang unik, Anda dapat membuang break ke pernyataan 'jika' untuk kinerja sehingga loop tidak perlu berulang-ulang di atas sisa array.
Patrick Borkowicz
@ Klor Terima kasih telah menjelaskan. Apakah baik untuk selalu membaca susunan mundur seperti pada jawabannya?
kittu
38

Katakanlah Anda ingin menghapus objek kedua dengan properti bidang itu.

Dengan ES6 semudah ini.

myArray.splice(myArray.findIndex(item => item.field === "cStatus"), 1)
Peracek
sumber
7
Saya mencoba ini tetapi alih-alih "menghapus" item ke-3 dari array OP, kode Anda "difilter" dan hanya menampilkan item ke-3.
Compaq LE2202x
1
@ CompaqLE2202x 2 tahun kemudian mungkin sudah jelas bagi Anda, tetapi untuk pengembang di masa depan: splicemengubah array asli, jadi nilai yang Anda dapatkan kembali adalah item yang dihapus, tetapi jika Anda melihat myArrayitem itu nanti akan hilang.
David Mulder
17

Anda dapat menggunakan findIndex lodash untuk mendapatkan indeks elemen tertentu dan kemudian menggunakannya.

myArray.splice(_.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

Memperbarui

Anda juga dapat menggunakan ES6's findIndex ()

Metode findIndex () mengembalikan indeks elemen pertama dalam array yang memenuhi fungsi pengujian yang disediakan. Kalau tidak -1 dikembalikan.

myArray.splice(myArray.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);
Sridhar
sumber
Apa array adalah struktur pohon?
Forgottofly
@forgottofly struktur pohon? Saya pikir di myArraysini adalah berbagai objek.
Sridhar
4
Bagaimana jika array adalah struktur pohon var beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "tes berubah 23"}]}] dan saya ingin menghapus id: 23
Forgottofly
9

Berikut opsi lain menggunakan jQuery grep. Lewati truesebagai parameter ketiga untuk memastikan grep menghapus item yang cocok dengan fungsi Anda.

users = $.grep(users, function(el, idx) {return el.field == "money"}, true)

Jika Anda sudah menggunakan jQuery maka tidak ada shim yang diperlukan, yang bisa berguna sebagai lawan menggunakan Array.filter.

sifriday
sumber
8

Dalam ES6, hanya satu baris.

const arr = arr.filter(item => item.key !== "some value");

:)

Supun Kavinda
sumber
3

Berikut ini adalah kode jika Anda tidak menggunakan jQuery. Demo

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];

alert(myArray.length);

for(var i=0 ; i<myArray.length; i++)
{
    if(myArray[i].value=='money')
        myArray.splice(i);
}

alert(myArray.length);

Anda juga dapat menggunakan pustaka garis bawah yang memiliki banyak fungsi.

Underscore adalah pustaka sabuk utilitas untuk JavaScript yang menyediakan banyak dukungan pemrograman fungsional

Umair Saleem
sumber
5
Ini adalah contoh yang sangat berbahaya untuk ditinggalkan di web ... ini berfungsi dengan contoh data, tetapi tidak dengan yang lain. splice (i) berarti akan menghapus semua elemen dalam array yang dimulai pada dan setelah contoh pertama di mana nilainya adalah uang, yang turun tidak memenuhi persyaratan dari op sama sekali. Jika kami mengubah menjadi splice (i, 1) itu masih akan salah karena tidak akan mengevaluasi item berurutan berikutnya (Anda juga harus mengurangi i). Inilah sebabnya Anda harus memproses operasi penghapusan dalam array mundur, sehingga menghapus item tidak mengubah indeks dari item berikutnya untuk diproses
Chris Schaller
3
var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];
console.log(myArray.length); //3
myArray = $.grep(myArray, function(element, index){return element.field == "money"}, true);
console.log(myArray.length); //2

Elemen adalah objek dalam array. Parameter ke-3 trueberarti akan mengembalikan array elemen yang gagal logika fungsi Anda, falseberarti akan mengembalikan array elemen yang gagal logika fungsi Anda.

Sandeep berpasir
sumber
3

Berdasarkan beberapa komentar di atas di bawah ini adalah kode cara menghapus objek berdasarkan nama kunci dan nilai kunci

 var items = [ 
  { "id": 3.1, "name": "test 3.1"}, 
  { "id": 22, "name": "test 3.1" }, 
  { "id": 23, "name": "changed test 23" } 
  ]

    function removeByKey(array, params){
      array.some(function(item, index) {
        return (array[index][params.key] === params.value) ? !!(array.splice(index, 1)) : false;
      });
      return array;
    }

    var removed = removeByKey(items, {
      key: 'id',
      value: 23
    });

    console.log(removed);
JackTheKnife
sumber
3

Menggunakan perpustakaan lodash :

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];
var newArray = _.remove(myArray, function(n) {
  return n.value === 'money';;
});
console.log('Array');
console.log(myArray);
console.log('New Array');
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>

Parth Raval
sumber
1

Solusi jAndy mungkin yang terbaik, tetapi jika Anda tidak bisa mengandalkan filter, Anda bisa melakukan sesuatu seperti:

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: "money"}
];

myArray.remove_key = function(key){
    var i = 0, 
        keyval = null;
    for( ; i < this.length; i++){
        if(this[i].field == key){
            keyval = this.splice(i, 1);
            break;
        }
    }
    return keyval;
}
Rob M.
sumber
1
Mengapa saya tidak dapat mengandalkan filter ()?
imperium2335
2
Karena itu adalah bagian dari JavaScript 1.6, yang tidak didukung oleh IE8 dan di bawah atau browser yang lebih lama.
Rob M.
-1

Menggunakan perpustakaan lodash itu sederhana seperti ini

_.remove(myArray , { field: 'money' });
Gimnath
sumber