Bagaimana cara menghapus objek dari array asosiatif javascript?

619

Misalkan saya punya kode ini:

var myArray = new Object();
myArray["firstname"] = "Bob";
myArray["lastname"] = "Smith";
myArray["age"] = 25;

Sekarang jika saya ingin menghapus "nama belakang"? .... apakah ada yang setara
myArray["lastname"].remove()?

(Saya perlu elemen hilang karena jumlah elemen penting dan saya ingin menjaga semuanya tetap bersih.)

djot
sumber
27
Kiat: jangan bingung membuat array dan peta. Beberapa bahasa, seperti php, memiliki objek tunggal untuk keduanya. Meskipun Anda menggunakan tipe yang tepat di sini (Object baru ()) Anda menamakannya myArray, itu hanya masalah standar untuk bahasa.
Juan Mendes
Jangan lupa bahwa JavaScript adalah jenis-kurang dan semuanya adalah objek. Lihat jawaban Saul di bawah ini.
stevek
4
@StephanKristyn - tepatnya, JS memiliki tipe tetapi dengan cara yang dinamis dan lemah . Sebagai contoh, walaupun variabel-variabelnya memang tidak bertipe, nilainya tidak. Itu adalah bagian yang dinamis . Lemah menunjukkan bahwa operasi antara berbagai jenis nilai tidak didefinisikan secara ketat dan bergantung pada konversi di belakang layar; misalnya "Test" + {};adalah pernyataan JS yang benar-benar valid.
Saul

Jawaban:

1135

Objek dalam JavaScript dapat dianggap sebagai array asosiatif, kunci pemetaan (properti) ke nilai.

Untuk menghapus properti dari objek dalam JavaScript, Anda menggunakan deleteoperator:

const o = { lastName: 'foo' }
o.hasOwnProperty('lastName') // true
delete o['lastName']
o.hasOwnProperty('lastName') // false

Perhatikan bahwa ketika deletediterapkan ke properti indeks dari Array, Anda akan membuat array yang jarang diisi (mis., Array dengan indeks yang hilang).

Ketika bekerja dengan instance Array, jika Anda tidak ingin membuat array yang jarang diisi - dan biasanya tidak - maka Anda harus menggunakan Array#spliceatau Array#pop.

Perhatikan bahwa deleteoperator dalam JavaScript tidak langsung membebaskan memori. Tujuannya adalah untuk menghapus properti dari objek. Tentu saja, jika properti yang dihapus menyimpan satu-satunya referensi yang tersisa untuk suatu objek o, maka oselanjutnya akan menjadi sampah yang dikumpulkan dengan cara normal.

Menggunakan deleteoperator dapat memengaruhi kemampuan mesin JavaScript untuk mengoptimalkan kode .

Dennis C
sumber
18
Ini akan menyebabkan masalah jika digunakan pada instance objek Array untuk menghapus elemen yang ada, misalnya delete myArray[0]. Lihat stackoverflow.com/a/9973592/426379 dan Menghapus elemen array
Saul
4
Masalah apa yang akan ditimbulkan?
Gottox
26
@Gottox - lengthProperti objek Array tetap tidak berubah.
Saul
12
@ Saul: akan ada masalah jika myArraybenar-benar digunakan sebagai array - tetapi tidak ( myArraynama yang disayangkan), itu adalah objek. Jadi dalam hal deleteini OK. Perhatikan bahwa meskipun itu dibuat sebagai new Array()dan digunakan sebagai array asosiatif itu masih akan OK. Peringatan Anda masih sesuatu yang harus diperhatikan jika seseorang menggunakan array nyata.
johndodo
2
@johndodo - Benar. Itulah sebabnya saya memulai komentar awal saya dengan This akan menyebabkan masalah jika digunakan pada instance objek Array . Namun saya lebih suka pendekatan yang bekerja dengan benar dalam semua kasus, lihat jawaban saya di bawah ini.
Saul
79

Semua objek dalam JavaScript diimplementasikan sebagai hashtables / array asosiatif. Jadi, berikut ini adalah yang setara:

alert(myObj["SomeProperty"]);
alert(myObj.SomeProperty);

Dan, sebagaimana telah ditunjukkan, Anda "menghapus" properti dari objek melalui deletekata kunci, yang dapat Anda gunakan dengan dua cara:

delete myObj["SomeProperty"];
delete myObj.SomeProperty;

Semoga info tambahan membantu ...

Jason Bunting
sumber
10
Perlu dicatat bahwa notasi titik tidak berfungsi jika properti tersebut bukan istilah yang sederhana. yaitu myObj['some;property']bekerja, tetapi myObj.some;propertytidak akan (karena alasan yang jelas). Juga mungkin tidak jelas bahwa Anda dapat menggunakan variabel dalam notasi braket, yaituvar x = 'SomeProperty'; alert(myObj[x])
Kip
2
"Semua objek dalam JavaScript diimplementasikan sebagai hashtable / array asosiatif." - false. V8 lebih suka menyimpan objek sebagai kelas tersembunyi + bidang padat. Hanya jika Anda melakukan hal-hal aneh pada mereka (seperti menghapus bidang) itu menyerah dan menggunakan peta hash di belakang layar.
John Dvorak
4
@ JanDvorak - hei, Anda tahu kapan jawaban ini awalnya ditulis, ya? Deskripsi itu dulu dan masih cukup untuk sebagian besar tujuan. Yang mengatakan, saya mengerti menjadi sangat membosankan. :)
Jason Bunting
41

Tak satu pun dari jawaban sebelumnya membahas fakta bahwa Javascript tidak memiliki array asosiatif untuk memulai - tidak ada arraytipe seperti itu, lihat typeof.

Apa yang dimiliki Javascript, adalah instance objek dengan properti dinamis. Ketika properti bingung dengan elemen-elemen dari instance objek Array maka Bad Things ™ pasti akan terjadi:

Masalah

var elements = new Array()

elements.push(document.getElementsByTagName("head")[0])
elements.push(document.getElementsByTagName("title")[0])
elements["prop"] = document.getElementsByTagName("body")[0]

console.log("number of elements: ", elements.length)   // returns 2
delete elements[1]
console.log("number of elements: ", elements.length)   // returns 2 (?!)

for (var i = 0; i < elements.length; i++)
{
   // uh-oh... throws a TypeError when i == 1
   elements[i].onmouseover = function () { window.alert("Over It.")}
   console.log("success at index: ", i)
}

Larutan

Untuk memiliki fungsi penghapusan universal yang tidak meledak pada Anda, gunakan:

Object.prototype.removeItem = function (key) {
   if (!this.hasOwnProperty(key))
      return
   if (isNaN(parseInt(key)) || !(this instanceof Array))
      delete this[key]
   else
      this.splice(key, 1)
};

//
// Code sample.
//
var elements = new Array()

elements.push(document.getElementsByTagName("head")[0])
elements.push(document.getElementsByTagName("title")[0])
elements["prop"] = document.getElementsByTagName("body")[0]

console.log(elements.length)                        // returns 2
elements.removeItem("prop")
elements.removeItem(0)
console.log(elements.hasOwnProperty("prop"))        // returns false as it should
console.log(elements.length)                        // returns 1 as it should
Saulus
sumber
8
Solusi ini memiliki dua masalah: menyembunyikan fakta bahwa array dan objek adalah binatang yang sama sekali berbeda di JS (Anda tahu itu, tetapi tampaknya OP tidak) dan menggunakan prototipe. OP akan lebih baik jika dia belajar tentang array dan objek (dan akan menamai variabelnya sesuai) - mencoba menyembunyikan perbedaan antara keduanya hanya akan membuatnya lebih banyak masalah. IMHO tentu saja.
johndodo
1
@johndodo - semua Arrayyang ada di JS adalah objek, coba typeof new Array();atau typeof []verifikasi. Arrayhanyalah jenis objek tertentu dan sama sekali bukan "binatang yang berbeda". Di JS, objek dibedakan berdasarkan nama konstruktor dan rantai prototipe mereka, lihat pemrograman berbasis Prototipe .
Saul
9
Anda tidak mengerti intinya. Saya tahu bahwa array juga objek, tetapi itu tidak berarti bijaksana untuk menggunakannya. Programmer harus memutuskan apakah dia ingin menggunakan sesuatu sebagai array (dengan push, pop, [], ...) atau sebagai objek / "array asosiatif". Padu padan bukanlah resep yang bagus, justru karena masalah yang coba disembunyikan oleh solusi Anda. Jika Anda memutuskan sebelumnya pola desain mana yang akan digunakan (array atau objek) tidak akan ada masalah seperti itu.
johndodo
7
@johndodo - Masalah apa yang sedang Anda bicarakan? Tujuan dari kode di atas adalah untuk mengatasi kekurangan deleteoperator sehubungan Arraydengan menyediakan fungsi polimorfik sederhana.
Saul
1
deletetidak memiliki kekurangan. deletedirancang untuk menghapus properti. Itu dia. Menerapkan operator hapus ke indeks array akan menghapus indeks itu. Apa lagi yang perlu dilakukan? Anda dibiarkan dengan array jarang, yang merupakan fitur bahasa. Jika Anda tidak ingin array yang jarang, jangan hapus indeks: gunakan spliceatau pop.
Ben Aston
35

Itu hanya menghapus menghapus objek tetapi masih mempertahankan panjang array yang sama.

Untuk menghapus Anda perlu melakukan sesuatu seperti:

array.splice(index, 1);
Bipin
sumber
11
Memang, tetapi dalam hal ini array tidak digunakan, hanya objek tua biasa, sehingga tidak memiliki metode panjang atau sambungan.
MooGoo
2
@Andreaa Panagiotidis Kecuali ketika kita tidak berbicara tentang Array, dalam hal itu salah 100% dari waktu 🙂
Drenai
17

Meskipun jawaban yang diterima benar, namun tidak ada penjelasan mengapa itu berhasil.

Pertama-tama, kode Anda harus mencerminkan fakta bahwa ini BUKAN array:

var myObject = new Object();
myObject["firstname"] = "Bob";
myObject["lastname"] = "Smith";
myObject["age"] = 25;

Perhatikan bahwa semua objek (termasuk Arrays) dapat digunakan dengan cara ini. Namun, jangan berharap fungsi array JS standar (pop, push, ...) berfungsi pada objek!

Seperti yang dikatakan dalam jawaban yang diterima, Anda dapat menggunakan deleteuntuk menghapus entri dari objek:

delete myObject["lastname"]

Anda harus memutuskan rute mana yang ingin Anda ambil - baik menggunakan objek (array asosiatif / kamus) atau menggunakan array (peta). Jangan pernah mencampur keduanya.

johndodo
sumber
6
Jawaban yang sangat bagus Saya hanya akan menyarankan siapa pun yang membaca ini bahwa Array dalam javascript tidak boleh diabstraksi sebagai 'peta', melainkan 'daftar'. Itu karena Anda tidak boleh mencoba untuk memiliki kontrol atas indeks elemen ketika menggunakan array. Jika Anda mencobanya ... yah, jangan: D
rodolfo42
6

Gunakan metode spliceuntuk sepenuhnya menghapus item dari array objek:

Object.prototype.removeItem = function (key, value) {
    if (value == undefined)
        return;

    for (var i in this) {
        if (this[i][key] == value) {
            this.splice(i, 1);
        }
    }
};

var collection = [
    { id: "5f299a5d-7793-47be-a827-bca227dbef95", title: "one" },
    { id: "87353080-8f49-46b9-9281-162a41ddb8df", title: "two" },
    { id: "a1af832c-9028-4690-9793-d623ecc75a95", title: "three" }
];

collection.removeItem("id", "87353080-8f49-46b9-9281-162a41ddb8df");
HarpyWar
sumber
1
ini adalah solusi yang lebih umum, dapat ditambahkan ke file js Anda dan metode ini akan tersedia untuk semua array, bukan hanya satu array.
Hussain
6

Seperti jawaban lain telah dicatat, apa yang Anda gunakan bukan array Javascript, tetapi objek Javascript, yang bekerja hampir seperti array asosiatif dalam bahasa lain kecuali bahwa semua kunci dikonversi ke string. Peta baru menyimpan kunci sebagai tipe aslinya.

Jika Anda memiliki array dan bukan objek, Anda bisa menggunakan fungsi .filter array , untuk mengembalikan array baru tanpa item yang ingin Anda hapus:

var myArray = ['Bob', 'Smith', 25];
myArray = myArray.filter(function(item) {
    return item !== 'Smith';
});

Jika Anda memiliki peramban dan jQuery yang lebih lama, jQuery memiliki $.grepmetode yang berfungsi serupa:

myArray = $.grep(myArray, function(item) {
    return item !== 'Smith';
});
Dzeimsas Zvirblis
sumber
penjelasan sempurna. Saya menggunakan filter untuk mencapai hasil yang diinginkan. Apakah Anda akan menjelaskan cara kerja item kembali untuk menghapus objek dari array. Saya berasumsi itu mengembalikan array asalkan tidak termasuk string yang Anda sertakan.
Edward
5

Anda menggunakan Object, Anda tidak memiliki array asosiatif untuk memulai. Dengan array asosiatif, menambah dan menghapus item berjalan seperti ini:

    Array.prototype.contains = function(obj) 
    {
        var i = this.length;
        while (i--) 
        {
            if (this[i] === obj) 
            {
                return true;
            }
        }
        return false;
    }


    Array.prototype.add = function(key, value) 
    {
        if(this.contains(key))
            this[key] = value;
        else
        {
            this.push(key);
            this[key] = value;
        }
    }


    Array.prototype.remove = function(key) 
    {
        for(var i = 0; i < this.length; ++i)
        {
            if(this[i] == key)
            {
                this.splice(i, 1);
                return;
            }
        }
    }



    // Read a page's GET URL variables and return them as an associative array.
    function getUrlVars()
    {
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');

        for(var i = 0; i < hashes.length; i++)
        {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }

        return vars;
    }



    function ForwardAndHideVariables() {
        var dictParameters = getUrlVars();

        dictParameters.add("mno", "pqr");
        dictParameters.add("mno", "stfu");

        dictParameters.remove("mno");



        for(var i = 0; i < dictParameters.length; i++)
        {
            var key = dictParameters[i];
            var value = dictParameters[key];
            alert(key + "=" + value);
        }
        // And now forward with HTTP-POST
        aa_post_to_url("Default.aspx", dictParameters);
    }


    function aa_post_to_url(path, params, method) {
        method = method || "post";

        var form = document.createElement("form");

        //move the submit function to another variable
        //so that it doesn't get written over if a parameter name is 'submit'
        form._submit_function_ = form.submit;

        form.setAttribute("method", method);
        form.setAttribute("action", path);

        for(var i = 0; i < params.length; i++)
        {
            var key = params[i];

            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
        }

        document.body.appendChild(form);
        form._submit_function_(); //call the renamed function
    }
Stefan Steiger
sumber
4

Anda dapat menghapus entri dari peta Anda dengan menetapkannya secara eksplisit ke 'tidak terdefinisi'. Seperti dalam kasus Anda:

myArray ["lastname"] = undefined;

Amytis
sumber
Ini bisa berguna dalam kasus-kasus di mana seseorang tidak yakin apakah kunci ada dalam kamus, tetapi ingin membersihkannya jika itu terjadi. Koreksi saya jika saya salah Amytis.
Hassan Baig
3

Jika karena alasan apa pun tombol hapus tidak berfungsi (seperti itu tidak berfungsi untuk saya)

Anda dapat memisahkannya dan kemudian memfilter nilai yang tidak ditentukan

// to cut out one element via arr.splice(indexToRemove, numberToRemove);
array.splice(key, 1)
array.filter(function(n){return n});

Jangan coba-coba dan rantai mereka karena sambungan mengembalikan elemen dihapus;

Leon
sumber
3

Kita juga bisa menggunakannya sebagai fungsi. Angular melempar beberapa kesalahan jika digunakan sebagai prototipe. Terima kasih @HarpyWar. Itu membantu saya memecahkan masalah.

var removeItem = function (object, key, value) {
    if (value == undefined)
        return;

    for (var i in object) {
        if (object[i][key] == value) {
            object.splice(i, 1);
        }
    }
};

var collection = [
    { id: "5f299a5d-7793-47be-a827-bca227dbef95", title: "one" },
    { id: "87353080-8f49-46b9-9281-162a41ddb8df", title: "two" },
    { id: "a1af832c-9028-4690-9793-d623ecc75a95", title: "three" }
];

removeItem(collection, "id", "87353080-8f49-46b9-9281-162a41ddb8df");
Omkar Kamale
sumber
2

Sangat mudah jika Anda memiliki ketergantungan garis bawah dalam proyek Anda -

_.omit(myArray, "lastname")
Vatsal
sumber
1

Dengan menggunakan "delete"kata kunci, itu akan menghapus elemen array dari array di javascript.

Sebagai contoh,

Pertimbangkan pernyataan berikut.

var arrayElementToDelete = new Object();

arrayElementToDelete["id"]           = "XERTYB00G1"; 
arrayElementToDelete["first_name"]   = "Employee_one";
arrayElementToDelete["status"]       = "Active"; 

delete arrayElementToDelete["status"];

Baris terakhir dari kode akan menghapus elemen array yang kuncinya "status" dari array.

Ravindra Miyani
sumber
0
var myArray = newmyArray = new Object(); 
myArray["firstname"] = "Bob";
myArray["lastname"] = "Smith";
myArray["age"] = 25;

var s = JSON.stringify(myArray);

s.replace(/"lastname[^,}]+,/g,'');
newmyArray = JSON.parse(p);

Tanpa perulangan / iterates kita mendapatkan hasil yang sama

Lalith kumar
sumber
0

Untuk "Array":

Jika Anda tahu indeksnya:

array.splice(index, 1);

Jika Anda tahu nilainya:

function removeItem(array, value) {
    var index = array.indexOf(value);
    if (index > -1) {
        array.splice(index, 1);
    }
    return array;
}

Jawaban yang paling banyak dipilih untuk deletebekerja dengan baik dalam hal objek tetapi tidak untuk array nyata. Jika saya menggunakannya deletemenghapus elemen dari loop tetapi membuat elemen emptydan panjang array tidak akan berubah. Ini mungkin menjadi masalah dalam beberapa skenario.

Sebagai contoh, jika saya melakukan myArray.toString () pada myArray setelah penghapusan melalui deleteitu menciptakan entri kosong yaitu ,,

Arvind K.
sumber
0

Satu-satunya metode yang bekerja untuk saya:

function removeItem (array, value) {
    var i = 0;
    while (i < array.length) {
        if(array[i] === value) {
            array.splice(i, 1);
        } else {
            ++i;
        }
    }
    return array;
}

pemakaian:

var new = removeItem( ["apple","banana", "orange"],  "apple");
// ---> ["banana", "orange"]
T.Todua
sumber
Mengapa tidak menggunakan filter saja? ini adalah kasus penggunaan sempurna untuk filter
Code Maniac