JavaScript'te ilişkilendirilebilir dizide anahtar olarak bir tamsayının kullanılması


104

Yeni bir JavaScript dizisi oluşturduğumda ve anahtar olarak bir tamsayı kullandığımda, o dizinin tam sayıya kadar her bir elemanı tanımsız olarak yaratılıyor.

Örneğin:

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

2298 tanımsız ve bir 'Bazı dizeler' çıktılar.

JavaScript'in bir tam sayı yerine 2300'ü bir dize olarak kullanmasını nasıl sağlayabilirim veya 2299 boş dizini başlatmasını nasıl engellemeliyim?

Yanıtlar:


131

İnsanların söylediği gibi bir nesne kullanın. Ancak, not sen ki değil anahtarları tamsayı var. JavaScript , tamsayıyı bir dizeye dönüştürecektir . Aşağıdaki çıktılar 20, tanımsız değil:

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

12
+1 Bunun Diziler için bile geçerli olduğuna dikkat edin! bakınız stackoverflow.com/questions/1450957/…
bobince

1
@bobince: Dahili olarak, tabii. Bununla birlikte, mantıksal olarak , dizilerin tam sayı "anahtarları" vardır.
Orbit'te Hafiflik Yarışları

1
Lütfen, anahtar olarak tamsayı kullanmanın dizinizin uzunluğunu değiştireceğini unutmayın. Bunun yerine kesinlikle Object kullanmalısınız. Sadece anahtar olarak facebook kimliğini kullanmak istedim ve JSON.stringify makinemi çökertecekti;)
Krystian

2
@LightnessRacesinOrbit Dahili detaylar yine de sızabilir ve sizi ısırabilir. Bugün karşılaştığım şeyin bu basitleştirilmiş versiyonuna bakın: jsfiddle.net/cincodenada/pseujLex/2 Azaltıldığında yapmacık görünebilir, ancak daha büyük bir betiğin mantıklı bir parçasıydı (ve CoffeeScript'te biraz daha az tartışıldı: jsfiddle.net/ cincodenada / oojr7Ltn / 2 ). Bu görünen uygulama detayı bugün bana biraz hata avına mal oldu.
cincodenada

2
Tam olmayan sayılar için küçük bir not: 0.25ve .25aynı dizeye çözümleyin "0.25". Dolayısıyla, kesirli anahtarlar 0.25kullanıyorsanız 0.25, sayısal olarak ayarlanmış bir anahtarın özelliğini kullanarak alabilirsiniz .25, "0.25"ancak bunu kullanamazsınız ".25".
Sandy Gifford

35

Sadece bir nesne kullanabilirsiniz:

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

16
Hala dizeye atılıyor.
2016'da

1
@ drew010 evet, Javascript'in nesneleri yalnızca dizelerle indekslemeye izin veriyor.
Pithikos

22

İnsanların dediği gibi, JavaScript bir sayı dizisini tam sayıya çevirecektir, bu nedenle doğrudan ilişkilendirilebilir bir dizi üzerinde kullanmak mümkün değildir, ancak nesneler sizin için benzer şekilde çalışacaktır.

Nesnenizi oluşturabilirsiniz:

var object = {};

Ve dizi çalıştıkça değerleri ekleyin:

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

Bu size şunları verecektir:

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

Bundan sonra, diğer dillerdeki bir dizi gibi anahtarı alarak erişebilirsiniz:

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

Test ettim ve çalışıyorum.


17

Kullanım durumu koleksiyonunda verilerini depolamak ise o zaman ECMAScript 6 sağlamaktadır Maptürü.

Başlatması daha ağır.

İşte bir örnek:

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

Sonuç:

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

11

Diğer cevapların derlenmesi:

Nesne

var test = {};

Bir sayıyı yeni bir özelliğin anahtarı olarak kullanırken, sayı bir dizeye dönüşür:

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

Aynı numarayı kullanarak mülkün değerine erişirken, sayı tekrar bir dizeye dönüştürülür:

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

Anahtarları nesneden alırken, sayılara geri dönmeyecekler:

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

Harita

ECMAScript 6, Map nesnesinin kullanımına izin verir ( dokümantasyon , Object ile bir karşılaştırma ). Kodunuzun yerel olarak yorumlanması amaçlanıyorsa veya ECMAScript 6 uyumluluk tablosu amaçlarınız için yeterince yeşil görünüyorsa, bir Harita kullanmayı düşünün:

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

Daha iyisi ve kötüsü için hiçbir tür dönüştürme yapılmaz:

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

4

Dizi yerine bir nesne kullanın. JavaScript'teki diziler ilişkilendirilebilir diziler değildir. İsimleri tamsayılara benzeyen tüm özelliklerle ilişkili sihir içeren nesnelerdir. Geleneksel dizi benzeri bir yapı olarak kullanmıyorsanız, bu sihir istediğiniz şey değildir.

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

1
Onlar yapabilirsiniz ilişkisel diziler olabilir, ama onlar set özelliklerini adında var olabilir nesneler de vardır diye. Ancak bu, işleri saçma bir şekilde kafa karıştırıcı hale getirir ve bu nedenle evet, nesnelerin kullanılması çok daha iyidir.
Graza

Diziler asla ilişkisel Graza olamaz. Anahtarları bir dizide kullanmayı denerseniz ve daha sonra bunların üzerinde yinelerseniz, dizilerin tüm varsayılan yöntemlerini ve özelliklerini de yinelediğinizi fark edeceksiniz -> pek arzu edilmez.
Swizec Teller

@Swizec - tam olarak neden "gülünç kafa karıştırıcı" dedim. Sen edebilir bir ilişkisel dizi olarak bir dizi kullanmak - ad / değer çiftleri olarak, ancak bunları yineleme asla istemem! (Sadece teknik bir
noktaya

evet, ama yinelediklerinde belirli bir sırada değiller (yani sıra garanti edilmez), bu onları numaralandırmanın amacıdır, bu yüzden kafa karıştırmaktan çok daha kötüdür.
Julix

3

Dizi değil, Nesne kullanmayı deneyin:

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

3
Bu kesinlikle gitmenin yoludur. Bu şekilde, tek bir dizeyi depolamak için 2300 giriş uzunluğunda bir dizi oluşturmazsınız.
Krystian

2
@Krystian JS dizileri sahte dizilerdir. Çalıştırın var a = []; a[Math.pow(2, 30)] = 'hello';ve tarayıcı / bellek kullanımının bir gigabayttan fazla a.lengtharttığını görmezsiniz, ancak 1073741824 olduğunu göreceksiniz. yeterince seyrek.
Andy

2

Özellik adı bir tam sayı olduğunda ilişkilendirilebilir dizi özelliğinin değerini alın:

Özellik adlarının tam sayı olduğu bir ilişkilendirilebilir dizi ile başlayarak :

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

Öğeleri diziye itin:

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

Dizide döngü yapın ve özellik değeriyle bir şeyler yapın.

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

Konsol çıktısı şu şekilde görünmelidir:

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

Gördüğünüz gibi, ilişkilendirilebilir dizi sınırlamasını aşabilir ve bir özellik adının bir tamsayı olmasını sağlayabilirsiniz.

NOT: Örneğimdeki ilişkilendirilebilir dizi, Dictionary <string, string> [] nesnesini serileştirdiyseniz sahip olacağınız JSON içeriğidir.



0

Bazen anahtarlarım için bir önek kullanıyorum. Örneğin:

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

obj = {};

obj[key] = val;

Artık onlara erişmekte sorun yaşamıyorsunuz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.