Menggunakan integer sebagai kunci dalam array asosiatif di JavaScript


102

Ketika saya membuat array JavaScript baru, dan menggunakan integer sebagai kunci, setiap elemen dari array tersebut hingga integer dibuat sebagai tidak terdefinisi.

Sebagai contoh:

var test = new Array();
test[2300] = 'Some string';
console.log(test);

akan menampilkan 2298 undefined dan satu 'Some string'.

Bagaimana cara mendapatkan JavaScript agar menggunakan 2300 sebagai string alih-alih integer, atau bagaimana cara mencegahnya membuat 2299 indeks kosong?

Jawaban:


128

Gunakan sebuah objek, seperti yang dikatakan orang. Namun, perhatikan bahwa Anda tidak dapat memiliki kunci integer. JavaScript akan mengubah integer menjadi string . Output berikut 20, tidak ditentukan:

var test = {}
test[2300] = 20;
console.log(test["2300"]);

12
+1 Perhatikan bahwa ini bahkan berlaku untuk Array! lihat stackoverflow.com/questions/1450957/…
bobince

1
@bobince: Secara internal, tentu. Namun, secara logika , array memiliki "kunci" integer.
Balapan Ringan di Orbit

1
Harap dicatat, bahwa menggunakan integer sebagai kunci akan mengubah panjang array Anda. Anda pasti harus menggunakan Object sebagai gantinya. Saya hanya ingin menggunakan id facebook sebagai kuncinya, dan JSON.stringify akan merusak mesin saya;)
Krystian

2
@LightnessRacesinOrbit Detail internal masih bisa bocor dan menggigit Anda. Lihat versi yang disederhanakan dari apa yang saya hadapi hari ini: jsfiddle.net/cincodenada/pseujLex/2 Ini mungkin tampak dibuat-buat ketika dikurangi, tetapi merupakan bagian yang masuk akal dari skrip yang lebih besar (dan sedikit kurang dibuat-buat di CoffeeScript: jsfiddle.net/ cincodenada / oojr7Ltn / 2 ). Detail implementasi yang tampak ini membuat saya kehilangan biaya untuk berburu bug hari ini.
cincodenada

1
Catatan kecil untuk bilangan bukan bilangan bulat: 0.25dan .25selesaikan ke string yang sama "0.25". Jadi, jika Anda menggunakan kunci pecahan, Anda dapat mengambil milik kunci numerik yang ditetapkan 0.25menggunakan 0.25, .25, "0.25"tapi tidak ".25".
Sandy Gifford

34

Anda bisa menggunakan objek:

var test = {}
test[2300] = 'Some string';

16
Masih dilemparkan ke string.
imbang010

1
@ drew010 ya, objek Javascript memungkinkan pengindeksan dengan string saja.
Pithikos

22

Seperti yang dikatakan orang, JavaScript akan mengubah string angka menjadi integer, jadi tidak mungkin untuk digunakan secara langsung pada array asosiatif, tetapi objek akan bekerja untuk Anda dengan cara yang sama menurut saya.

Anda dapat membuat objek Anda:

var object = {};

Dan tambahkan nilai saat array berfungsi:

object[1] = value;
object[2] = value;

Ini akan memberi Anda:

{
  '1': value,
  '2': value
}

Setelah itu Anda dapat mengaksesnya seperti array dalam bahasa lain mendapatkan kuncinya:

for(key in object)
{
   value = object[key] ;
}

Saya telah menguji dan bekerja.


17

Jika kasus penggunaan menyimpan data dalam koleksi maka ECMAScript 6 menyediakan Maptipenya.

Hanya lebih berat untuk menginisialisasi.

Berikut ini contohnya:

const map = new Map();
map.set(1, "One");
map.set(2, "Two");
map.set(3, "Three");

console.log("=== With Map ===");

for (const [key, value] of map) {
    console.log(`${key}: ${value} (${typeof(key)})`);
}

console.log("=== With Object ===");

const fakeMap = {
    1: "One",
    2: "Two",
    3: "Three"
};

for (const key in fakeMap) {
    console.log(`${key}: ${fakeMap[key]} (${typeof(key)})`);
}

Hasil:

=== With Map ===
1: One (number)
2: Two (number)
3: Three (number)
=== With Object ===
1: One (string)
2: Two (string)
3: Three (string)

11

Menyusun jawaban lain:

Obyek

var test = {};

Saat menggunakan angka sebagai kunci properti baru, angka tersebut berubah menjadi string:

test[2300] = 'Some string';
console.log(test['2300']);
// Output: 'Some string'

Saat mengakses nilai properti menggunakan nomor yang sama, nomor tersebut diubah menjadi string lagi:

console.log(test[2300]);
// Output: 'Some string'

Namun, ketika mendapatkan kunci dari objek, mereka tidak akan diubah kembali menjadi angka:

for (var key in test) {
    console.log(typeof key);
}
// Output: 'string'

Peta

ECMAScript 6 memungkinkan penggunaan objek Peta ( dokumentasi , perbandingan dengan Objek ). Jika kode Anda dimaksudkan untuk diinterpretasikan secara lokal atau tabel kompatibilitas ECMAScript 6 tampak cukup hijau untuk tujuan Anda, pertimbangkan untuk menggunakan Peta:

var test = new Map();
test.set(2300, 'Some string');
console.log(test.get(2300));
// Output: 'Some string'

Tidak ada jenis konversi yang dilakukan, menjadi lebih baik dan lebih buruk:

console.log(test.get('2300'));
// Output: undefined
test.set('2300', 'Very different string');
console.log(test.get(2300));
// Output: 'Some string'

4

Gunakan objek alih-alih array. Array dalam JavaScript bukanlah array asosiatif. Mereka adalah objek dengan sihir yang terkait dengan properti apa pun yang namanya terlihat seperti bilangan bulat. Keajaiban itu bukanlah yang Anda inginkan jika Anda tidak menggunakannya sebagai struktur seperti larik tradisional.

var test = {};
test[2300] = 'some string';
console.log(test);

1
Mereka dapat berupa array asosiatif, tetapi hanya karena mereka juga objek yang dapat memiliki kumpulan properti bernama. Tapi ini hanya membuat hal-hal menjadi sangat membingungkan, jadi ya, objek jauh lebih baik untuk digunakan.
Graza

Array tidak pernah bisa menjadi Graza asosiatif. Jika Anda mencoba menggunakan kunci dalam array dan kemudian mengulanginya, Anda akan melihat bahwa Anda juga melakukan iterasi melalui semua metode default dan properti array -> tidak terlalu diinginkan.
Swizec Teller

@Swizec - tepatnya mengapa saya mengatakan "sangat membingungkan". Anda dapat menggunakan array sebagai array asosiatif - yaitu sebagai pasangan nama / nilai, tetapi Anda tidak akan pernah ingin mengulanginya! (Saya hanya menunjukkan masalah teknis, jelas bukan sesuatu yang saya sarankan untuk dilakukan)
Graza

ya, tapi saat mengulang mereka tidak dalam urutan tertentu (yaitu urutan tidak dijamin), yang akan menjadi poin penomoran mereka, jadi ini jauh lebih buruk daripada sekedar membingungkan.
Julix

3

Coba gunakan Object, bukan Array:

var test = new Object(); test[2300] = 'Some string';

3
Ini pasti cara untuk pergi. Dengan cara ini Anda tidak akan membuat 2300 entri long array untuk menyimpan satu string.
Krystian

2
Array @Krystian JS adalah array palsu. Jalankan var a = []; a[Math.pow(2, 30)] = 'hello';dan Anda tidak akan melihat penggunaan browser / memori melonjak lebih dari satu gigabyte, tetapi yang Anda lihat a.lengthadalah 1073741824. VM dengan jelas menyimpan beberapa "array" menggunakan beberapa struktur data lain, saya rasa hanya sebuah hashtable, setidaknya jika mereka cukup jarang.
Andy

2

Dapatkan nilai untuk properti array asosiatif jika nama properti adalah bilangan bulat:

Dimulai dengan array asosiatif dimana nama propertinya adalah integer:

var categories = [
    {"1": "Category 1"},
    {"2": "Category 2"},
    {"3": "Category 3"},
    {"4": "Category 4"}
];

Dorong item ke array:

categories.push({"2300": "Category 2300"});
categories.push({"2301": "Category 2301"});

Ulangi array dan lakukan sesuatu dengan nilai properti.

for (var i = 0; i < categories.length; i++) {
    for (var categoryid in categories[i]) {
        var category = categories[i][categoryid];
        // Log progress to the console
        console.log(categoryid + ": " + category);
        //  ... do something
    }
}

Output konsol akan terlihat seperti ini:

1: Category 1
2: Category 2
3: Category 3
4: Category 4
2300: Category 2300
2301: Category 2301

Seperti yang Anda lihat, Anda bisa mengatasi batasan array asosiatif dan memiliki nama properti berupa integer.

CATATAN: Array asosiatif dalam contoh saya adalah konten JSON yang akan Anda miliki jika Anda membuat serial objek <string, string> [] Kamus.


0

Gunakan objek - dengan integer sebagai kuncinya - daripada array.


0

Terkadang saya menggunakan prefiks untuk kunci saya. Sebagai contoh:

var pre = 'foo',
    key = pre + 1234

obj = {};

obj[key] = val;

Sekarang Anda tidak memiliki masalah untuk mengaksesnya.

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.