JavaScript ilişkilendirilebilir dizisinde dinamik olarak anahtarlar oluşturma


199

Javascript ilişkilendirilebilir dizilerinde dinamik olarak anahtarları nasıl oluşturabilirim?

Şimdiye kadar bulduğum tüm belgeler, önceden oluşturulmuş anahtarları güncellemektir:

 arr['key'] = val;

Böyle bir dize var " name = oscar "

Ve bunun gibi bir şeyle sonuçlanmak istiyorum:

{ name: 'whatever' }

Ben dize bölmek ve ilk öğe olsun, ve ben bir sözlük koymak istiyorum.

kod

var text = ' name = oscar '
var dict = new Array();
var keyValuePair = text.split(' = ');
dict[ keyValuePair[0] ] = 'whatever';
alert( dict ); // prints nothing.

24
Kolaylık sağlamak için Eugene'in cevabına bağlantı atla
user56reinstatemonica8

Yanıtlar:


143

İlk örneği kullanın. Anahtar yoksa eklenir.

var a = new Array();
a['name'] = 'oscar';
alert(a['name']);

'Oscar' içeren bir mesaj kutusu açılacaktır.

Deneyin:

var text = 'name = oscar'
var dict = new Array()
var keyValuePair = text.replace(/ /g,'').split('=');
dict[ keyValuePair[0] ] = keyValuePair[1];
alert( dict[keyValuePair[0]] );

Bunu emin olmak için Firefox'ta örnek olarak çalıştırdım. 'Name' i tırnak içine aldığınızdan emin misiniz?
tvanfosson

1
Ahh hayır, çünkü anahtarı statik olarak değil "dinamik olarak" oluşturuyorum. Yine de iki kez kontrol edeyim :)
OscarRyz

2
Lütfen Danny'nin daha eksiksiz açıklamasına bakın. Bir dizine sahip bir for döngüsünde (myarray [i] gibi) dizi değerlerine başvuramazsınız. Umarım bu çok kafa karıştırıcı değildir.
MK_Dev

4
Daha da iyisi Dizi prototip dahildir vb .length, .slice (), sahip yükünü önlemek için bir nesne (braket {} notasyonu) kullanmaktır
bjornl

489

Her nasılsa, tüm örnekler iyi çalışırken, aşırı karmaşıktır:

  • Onlar kullanmak new Array()basit bir ilişkisel dizi (AKA Sözlük) için bir overkill (ve bir havai) olan.
  • Daha iyileri kullanır new Object(). İyi çalışıyor, ama neden tüm bu ekstra yazım?

Bu soru "acemi" olarak etiketlendi, bu yüzden basitleştirelim.

Bir sözlüğü JavaScript'te veya "JavaScript'in neden özel bir sözlük nesnesi yok?"

// create an empty associative array (in JavaScript it is called ... Object)
var dict = {};   // huh? {} is a shortcut for "new Object()"

// add a key named fred with value 42
dict.fred = 42;  // we can do that because "fred" is a constant
                 // and conforms to id rules

// add a key named 2bob2 with value "twins!"
dict["2bob2"] = "twins!";  // we use the subscript notation because
                           // the key is arbitrary (not id)

// add an arbitrary dynamic key with a dynamic value
var key = ..., // insanely complex calculations for the key
    val = ...; // insanely complex calculations for the value
dict[key] = val;

// read value of "fred"
val = dict.fred;

// read value of 2bob2
val = dict["2bob2"];

// read value of our cool secret key
val = dict[key];

Şimdi değerleri değiştirelim:

// change the value of fred
dict.fred = "astra";
// the assignment creates and/or replaces key-value pairs

// change value of 2bob2
dict["2bob2"] = [1, 2, 3];  // any legal value can be used

// change value of our secret key
dict[key] = undefined;
// contrary to popular beliefs assigning "undefined" does not remove the key

// go over all keys and values in our dictionary
for (key in dict) {
  // for-in loop goes over all properties including inherited properties
  // let's use only our own properties
  if (dict.hasOwnProperty(key)) {
    console.log("key = " + key + ", value = " + dict[key]);
  }
}

Değerleri silmek de kolaydır:

// let's delete fred
delete dict.fred;
// fred is removed, the rest is still intact

// let's delete 2bob2
delete dict["2bob2"];

// let's delete our secret key
delete dict[key];

// now dict is empty

// let's replace it, recreating all original data
dict = {
  fred:    42,
  "2bob2": "twins!"
  // we can't add the original secret key because it was dynamic,
  // we can only add static keys
  // ...
  // oh well
  temp1:   val
};
// let's rename temp1 into our secret key:
if (key != "temp1") {
  dict[key] = dict.temp1; // copy the value
  delete dict.temp1;      // kill the old key
} else {
  // do nothing, we are good ;-)
}

2
Merhaba, eski cevaba yanıt verdiğimi biliyorum, ancak Google'da üst sıralarda yer alıyor, bu yüzden yine de soracağım. Örneğinizde "orijinal gizli anahtarı ekleyemediğimiz için dinamik olduğu için, yalnızca statik anahtarlar ekleyebileceğimiz" anlamında biraz kafam karıştı.
Karel Bílek

1
Tam olarak söylediği anlamına gelir: değerini bilmiyoruz, bu yüzden onu sabit olarak gösteremeyiz, bu da bir nesne değişmezinde bir anahtar belirtirken gereklidir.
Eugene Lazutkin

3
Ancak, bir değişkeni doğrudan {} içinde bir anahtar olarak veya nokta gösterimli bir anahtar olarak kullanamasanız bile, "orijinal gizli anahtarı dinamik olduğu için ekleyemeyiz" tek başına doğru değildir. Yine de örnekte erken gösterdiğiniz gibi "dict [key] = val" aracılığıyla dinamik bir anahtar ekleyebiliriz. Sınırlama, anahtarın kendisi yerine {} -notation kullanılmasıdır.
Zut

8
Bu Sheldon Cooper'ın cevabı gibi görünüyor :)
jpatiaga

4
mükemmel tam cevap, varsayılan olmalı
Dennis Golomazov

29

Javascript ilişkilendirilebilir dizilere sahip değildir , nesneleri vardır .

Aşağıdaki kod satırlarının tümü aynı şeyi yapar - bir nesne üzerindeki 'ad' alanını 'orion' olarak ayarlayın.

var f = new Object(); f.name = 'orion';
var f = new Object(); f['name'] = 'orion';
var f = new Array(); f.name = 'orion';
var f = new Array(); f['name'] = 'orion';
var f = new XMLHttpRequest(); f['name'] = 'orion';

İlişkilendirilebilir bir diziniz var gibi görünüyor çünkü bir Arrayde bir Object- ancak aslında diziye bir şeyler eklemiyorsunuz, nesne üzerindeki alanları ayarlıyorsunuz.

Şimdi bu temizlendi, işte senin örnek için çalışan bir çözüm

var text = '{ name = oscar }'
var dict = new Object();

// Remove {} and spaces
var cleaned = text.replace(/[{} ]/g, '');

// split into key and value
var kvp = cleaned.split('=');

// put in the object
dict[ kvp[0] ] = kvp[1];
alert( dict.name ); // prints oscar.

Metin dizesinin aslında kıvırcık parantezleri olduğunu varsayarsak, az ya da çok JSON gibi davranabilirsiniz .. = işaretini a: ile değiştirin ve değerlendirmek için bir nesneniz var ..
neonski

1
Hata, dize düzgün sınırlanmamış. Hiçbir normal ifade düzeltilemez.
neonski

9

MK_Dev'e yanıt olarak, kişi yinelenebilir, ancak art arda değil .(Bunun için açıkça bir dizi gereklidir)

Hızlı google araması ortaya çıkıyor Javascript karma tablolar

Bir karma içindeki değerler üzerinde döngü için örnek kod (yukarıda belirtilen bağlantıdan):

var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;

// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

5

Orijinal Kod (Satır numaralarını ekledim, böylece onlara başvurabilirsiniz):

1  var text = ' name = oscar '
2  var dict = new Array();
3  var keyValuePair = text.split(' = ');
4  dict[ keyValuePair[0] ] = 'whatever';
5  alert( dict ); // prints nothing.

Neredeyse...

  • satır 1: trimmetin üzerinde bir açık yapmalısınız name = oscar.
  • satır 3: her zaman eşit etrafında boşluklar olduğu sürece tamam. trimsatır 1'de olmamak daha iyi olabilir , =her anahtarı kullanın ve kırpın
  • 3'ten sonra ve 4'ten önce bir satır ekleyin:

    key = keyValuePair[0];`
  • satır 4: Şimdi şöyle olur:

    dict[key] = keyValuePair[1];
  • satır 5: Şuna değiştir:

    alert( dict['name'] );  // it will print out 'oscar'

Söylemeye çalıştığım dict[keyValuePair[0]]şey çalışmıyor, bir dize ayarlamanız keyValuePair[0]ve ilişkilendirilebilir anahtar olarak kullanmanız gerekiyor . Benimkini çalıştırmamın tek yolu bu. Kurduktan sonra, sayısal dizinle başvurabilir veya tırnak işaretleri içine alabilirsiniz.

Umarım yardımcı olur.


4

Tüm modern tarayıcılar destekleyen Harita anahtar / değer veri darlık olduğunu. Bir haritayı Nesne'den daha iyi hale getirmenin birkaç nedeni vardır:

  • Bir Nesnenin bir prototipi vardır, dolayısıyla haritada varsayılan anahtarlar vardır.
  • Bir Nesnenin anahtarları, bir Harita için herhangi bir değer olabileceği Dizelerdir.
  • Bir Nesnenin boyutunu takip etmek zorunda kalırken Harita boyutunu kolayca elde edebilirsiniz.

Misal:

var myMap = new Map();

var keyObj = {},
    keyFunc = function () {},
    keyString = "a string";

myMap.set(keyString, "value associated with 'a string'");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");

myMap.size; // 3

myMap.get(keyString);    // "value associated with 'a string'"
myMap.get(keyObj);       // "value associated with keyObj"
myMap.get(keyFunc);      // "value associated with keyFunc"

Başka nesnelerden referans alınmayan anahtarların çöp toplanmasını istiyorsanız , Harita yerine WeakMap kullanmayı düşünün .



1
var myArray = new Array();
myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
// show the values stored
for (var i in myArray) {
    alert('key is: ' + i + ', value is: ' + myArray[i]);
}

bu tamam ama dizi nesnesinin her özelliği ile yinelenir. yalnızca myArray.one, myArray.two ... özellikleri arasında yineleme yapmak istiyorsanız, bunu deneyin

myArray['one'] = 1;
myArray['two'] = 2;
myArray['three'] = 3;
myArray.push("one");
myArray.push("two");
myArray.push("three");
for(i=0;i<maArray.length;i++{
    console.log(myArray[myArray[i]])
}

şimdi hem myArray ["one"] ile erişebilir ve yalnızca bu özellikler üzerinden yineleyebilirsiniz.


Örneğinizdeki yanlışlık sayısını saydınız mı? :-) maArray, unutulmuş kapalı ')' ...
Brian Haak

Örnek için teşekkürler. Bir araya gelebilir Arrayve Objectsadece Objectağaçlarla çalışabiliriz ! Harika bir fikir! Yapmak çok faydalı Object.getOwnPropertyNames(obj/array)!
Brian Haak

1
var obj = {};

                for (i = 0; i < data.length; i++) {
                    if(i%2==0) {
                        var left = data[i].substring(data[i].indexOf('.') + 1);
                        var right = data[i + 1].substring(data[i + 1].indexOf('.') + 1);

                        obj[left] = right;
                        count++;
                    }
                }
                console.log("obj");
                console.log(obj);
                // show the values stored
                for (var i in obj) {
                    console.log('key is: ' + i + ', value is: ' + obj[i]);
                }

            }
        };

}

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.