Pertanyaan Hapus nilai dari js array tanpa mengurutkan ulang kunci


Saya memiliki larik, dan saya ingin menghapus hanya satu elemen, tetapi tanpa mengurutkan ulang kunci. Apakah ada cara mudah tanpa menggunakan delete atau membangun kembali seluruh array?

Atau alternatif membersihkan setelah menghapus untuk menyingkirkan nilai-nilai yang tidak terdefinisi, memperbaiki panjang lagi.

var array = ["valueone", "valuetwo"];

console.dir(array); // keys 0 and 1
array.splice(0, 1);
console.dir(array); // key 1 is now 0, do not want!

4
2018-03-05 21:50


asal


Jawaban:


Kamu bisa delete elemen array:

a = ['one', 'two'];
delete a[0];

// a is now [undefined, 'two'];

atau, atur a[0] secara eksplisit untuk undefined.

Perhatikan bahwa sebuah array .length parameter secara otomatis dikelola oleh sistem. Jika Anda sengaja mengaturnya ke angka yang lebih tinggi, Anda hanya akan mendapatkan seluruh beban undefined nilai untuk kunci yang hilang:

a.length = 10;
// a is now [undefined, 'two', undefined x 8]

Jika semantik ini tidak dapat diterima oleh Anda, maka Anda harus mempertimbangkan untuk menggunakan Object sebagai gantinya. Ini akan mempertahankan kunci Anda, dan mungkin lebih efisien, tetapi Anda kehilangan .length milik.


4
2018-03-05 21:54



tidak bisa Anda hanya secara eksplisit mengatur nilai ke tidak terdefinisi atau null atau string kosong. Apa yang Anda coba capai?

var arr = ['aaaa','bbb','ccc','ddd'];
    arr[0]= undefined;
    //or
    arr[0]= null;
    ///or
    arr[0]= "";
    arr.length; <--- 4

1
2018-03-05 22:00



Perbarui 2018-09-07

Jawaban ini sangat tidak bagus, menurut saya. Saya memberikan jawaban Bagaimana cara menghapus properti dari Objek JavaScript yang telah menerima lebih banyak perhatian dari saya selama bertahun-tahun dan mencakup kasus ini dan masuk ke lebih detail.

Intinya adalah, Anda harus menggunakan Array.prototype.splice dan Array.prototype.slice.

array.splice(start, n) mengembalikan subkumpulan array dari indeks start dengan n elemen berurutan, dan menghapus subkumpulan ini dari larik asli, membuat larik baru dalam proses.

let array = [1,2,3,4,5,6];
array.splice(2,3); // [3,4,5]
array; // [1,2,6]

array.slice(start, end) mengembalikan subkumpulan array dari indeks start untuk mengindeks end tanpa memutasikan aslinya. Perilaku sedikit berbeda splice, itulah mengapa saya lebih suka menyebutnya sebagai array.slice(start, start + n).

let array = [1,2,3,4,5,6];
array.slice(2, 2 + 3); // [3,4,5]
array; // [1,2,3,4,5,6]

Tentu saja kamu bisa mengatur indeks ke nilai sentinel suka null atau "", tetapi jika Anda ingin agar array tetap pada urutan yang sama setelah penghapusan, mungkin Anda harus mengubah pendekatan Anda - mengapa demikian "valuetwo" harus berada di indeks 1? Informasi berguna apa yang bahkan disimpan dalam struktur data ini jika isinya selalu sama dengan kunci yang diperlukan untuk mengaksesnya?


Jawaban aslinya ada di bawah. Dan jika saya akan menyimpan teks aslinya, mungkin saya harus menjelaskan mengapa itu adalah saran yang buruk.

Anda dapat menggunakan javascript delete kata kunci.

delete array[index];

Jangan lakukan ini. Jika array Anda homogen (sebagaimana seharusnya), maka ini akan merusak array Anda dengan memperkenalkan tipe kedua (undefined). Kamu harus menggunakan array.splice() seperti yang dibahas di atas, yang akan membuat larik baru dengan rentang yang ditentukan dihilangkan.

Sayangnya, ini menciptakan sebuah undefined indeks di dalam array

var arr = ['pie', 'cake', 'fish'];
delete arr[1];
arr; // ['pie', undefined, 'fish']

Inti masalah.

Anda juga bisa melakukan ini:

var arr = [9,8,7,6];
arr[1] = null;
arr;        // [9,null,7,6]
arr.length; // 4
var i = -1;
while(++i < arr.length){
    if(arr[i] && typeof(arr[i] === "number")){
        alert(arr[i]);
    }
}

Anda bisa, tetapi Anda tidak seharusnya. Tidak hanya ini tidak perlu, dan tidak melakukan sesuatu yang berguna (karena semua yang dilakukannya adalah menelepon alert), tetapi sebenarnya rusak.

if(arr[i] && typeof(arr[i] === "number")){
    alert(arr[i]);
}

Anda mungkin berharap ini hanya mencetak elemen kita jika itu bukan angka nol, tetapi sebenarnya juga akan berjalan untuk nilai-nilai seperti "foo", [] dan document.createElement("p"), karena typeof(arr[i] === "number") akan selalu mengembalikan nilainya "boolean", yang merupakan string tidak kosong, yang benar dan karenanya akan terevaluasi benar. Yang berarti satu-satunya persyaratan untuk alert disebut itu arr[i] itu benar. Hanya ada enam nilai di seluruh bahasa yang akan menyebabkan pernyataan ini jika tidak dieksekusi, dan itu adalah:

  • undefined
  • null
  • 0
  • "" (diucapkan "string kosong")
  • false
  • NaN

Atau, jika Anda TIDAK PERLU menggunakan array, Anda bisa menggunakan objek dan membuat semuanya lebih mudah:

var obj = {
    0: "first",
    1: "second",
    2: "third"
};
delete obj[1];
obj; // {0: "first", 2: "third"}
for(var i in obj){
    alert(obj[i]);
}

Yang dengan instan menghapus semua keuntungan menggunakan sebuah array. Sekarang Anda memiliki kumpulan data yang mungkin atau mungkin tidak heterogen, yang tidak dapat difilter, dipetakan, dikurangi atau diubah dengan cara apa pun, dan Anda harus menggunakan hal-hal seperti for(i in obj) (yang sangat rawan jika Anda berani menggunakan perpustakaan seperti jQuery) untuk mengulanginya. Untungnya hari ini kami memiliki barang-barang mewah seperti Object.keys(obj).map(k => obj[k]).forEach(function(el){ ... }), tapi itu bukan alasan untuk memiliki struktur data yang buruk.

Untuk mendapatkan panjang sebuah objek:

getLength = function(obj){
    var i = 0, l = 0;
    for(i in obj){
        l++;
    }
    return l;
}
getLength(obj); // 3

Sekali lagi, dengan array, ini tidak perlu.

Tetapi ingat bahwa objek mengurutkan indeks mereka date of creation, bukan> dengan nama. Ini seharusnya tidak menghasilkan blokade jalan.

Untuk mengurutkan indeks suatu objek menurut abjad:

sortObject = function (){
    var arr = [], i;
    for(i in this){
        arr.push({index:i,content:this[i]});
        delete this[i];
    }
    arr.sort();
    for(i in arr){
        var item = arr[i];
        this[item.index] = item.content;
    }
    return this; // make chainable
}
var obj = {
    acronym: "OOP",
    definition: "Object-Oriented Programming",
    article: "http://wikipedia.org/OOP"
};
sortObject.apply(obj); // indices are "acronym", "article", "definition"
array.sort(fn)

Inti dari suatu objek adalah bahwa propertinya tidak disortir. Menyortir daftar yang tidak disortir tidak akan berguna.

Hanya untuk menggambarkan berapa banyak array yang lebih baik dalam melakukan hal-hal array:

let array = ["pie", "cake", "fish", "brownie", "beef", ...];
/* do some stuff... */
array
.filter(el => exclude.indexOf(el) === -1)
.forEach(function(el){
    console.log(el);
});

jika exclude aku s ["cake", "brownie"], maka ini akan mencatat hal berikut ke konsol:

pie
fish
beef
...

Coba bayangkan berapa banyak baris kode yang tidak perlu yang diperlukan untuk melakukan hal yang sama dengan menggunakan pendekatan dari versi sebelumnya dari jawaban ini.


Semoga ini membantu

Semoga ini memperbarui membantu.


1
2018-03-05 22:47