JavaScript連想配列で動的にキーを作成する


199

JavaScriptの連想配列で動的にキーを作成するにはどうすればよいですか?

これまでに見つけたすべてのドキュメントは、すでに作成されているキーを更新することです。

 arr['key'] = val;

私はこのようなひもを持っています " name = oscar "

そして、私はこのようなもので終わりたいと思います:

{ name: 'whatever' }

つまり、文字列を分割して最初の要素を取得し、それを辞書に入れたいのです。

コード

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

24
便宜上、ユージーンの回答リンクをジャンプします
user56reinstatemonica8

回答:


142

最初の例を使用します。キーが存在しない場合は追加されます。

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

「oscar」を含むメッセージボックスをポップアップします。

試してください:

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

念のため、これをFirefoxのサンプルとして実行しました。「名前」は必ず引用符で囲みましたか?
tvanfosson 2008

1
ええと、いや、静的ではなく「動的」にキーを作成しているからです。とにかく再確認しましょう:)
OscarRyz 2008

2
ダニーのより完全な説明を参照してください。forループでインデックスを使用して配列値を参照することはできません(myarray [i]など)。混乱しすぎないように。
MK_Dev 2008

4
さらに良いのは、オブジェクト(ブラケット{}表記)を使用して、配列プロトタイプに含まれる.length、.slice()などのオーバーヘッドを回避することです
bjornl

488

どういうわけか、すべての例はうまく機能しますが、非常に複雑です。

  • 彼らはを使用しますnew Array()。これは、単純な連想配列(別名ディクショナリ)に対して過剰(およびオーバーヘッド)です。
  • 良いものを使用しますnew Object()。正常に動作しますが、なぜこの余分な入力がすべて必要なのですか

この質問には「初心者」というタグが付いているので、簡単にしましょう。

JavaScriptで辞書を使用するための非常に簡単な方法または「JavaScriptに特別な辞書オブジェクトがない理由」:

// 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];

次に、値を変更します。

// 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]);
  }
}

値の削除も簡単です:

// 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
こんにちは、私は古い回答に返信していることを知っていますが、Googleで上位にランクされているので、とにかく質問します。あなたの例では、「元の秘密鍵は動的だったので、追加できません。静的な鍵しか追加できない」とはどういう意味か混乱しています。
カレルビレク

1
これは正確に言っていることを意味します。その値がわからないため、定数として表すことはできません。これは、オブジェクトリテラルでキーを指定するときに必要です。
Eugene Lazutkin、2011

3
ただし、変数を{}で直接キーとして使用したり、ドット表記のキーとして使用したりすることはできませんが、「動的だったため、元のシークレットキーを追加することはできません」だけでは正しくありません。例の早い段階で示したように、「dict [key] = val」を通じて動的キーを追加することもできます。制限は、キー自体ではなく、{}表記を使用することです。
Zut

8
これはシェルドンクーパーの答えのようです:)
jpatiaga

4
完全な完全な回答、デフォルトにする必要があります
デニスゴロマゾフ2013

29

JavaScriptには連想配列はなくオブジェクトがあります

次のコード行はすべてまったく同じことを行います-オブジェクトの 'name'フィールドを 'orion'に設定します。

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';

Arrayもなので、連想配列があるように見えますが、Object実際には配列に何も追加しておらず、オブジェクトにフィールドを設定しています。

これで問題が解決したので、ここにあなたの例の実用的な解決策があります

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.

...あなたはevalのにオブジェクトを持っている:テキスト文字列は、実際に中括弧を持っている、あなたは多かれ少なかれJSONとして扱いしたと仮定すると...と=記号を置き換える
neonski

1
おっと、文字列が正しく区切られていません。正規表現で修正できないものはありません。
ネオンスキー2008

9

MK_Devに応じて、反復することはできますが、連続して行うことはできません(そのためには明らかに配列が必要です)

クイックグーグル検索はJavaScriptでハッシュテーブルを表示します

ハッシュの値をループするためのサンプルコード(前述のリンクから):

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

元のコード(行番号を追加して参照できるようにした):

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.

ほとんどそこに...

  • 1行目:trimonテキストを実行する必要がありますname = oscar
  • 3行目:常にあなたの周りにスペースがある限り問題ありません。trim1行目ではなく、=各keyValuePairを使用してトリミングする方がよい場合があります。
  • 3の後で4の前に行を追加します。

    key = keyValuePair[0];`
  • 4行目:次のようになります:

    dict[key] = keyValuePair[1];
  • 5行目:変更:

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

私が言おうとしていることは、dict[keyValuePair[0]]が機能しないことです。文字列をに設定し、keyValuePair[0]それを連想キーとして使用する必要があります。それが私の仕事をさせる唯一の方法です。設定後、数値インデックスまたは引用符付きのキーで参照できます。

お役に立てば幸いです。


4

最近のすべてのブラウザは、キー/値のデータ構造であるMapをサポートしています。ObjectよりMapを使用する理由はいくつかあります。

  • オブジェクトにはプロトタイプがあるため、マップにはデフォルトのキーがあります。
  • オブジェクトのキーは文字列であり、マップの任意の値にすることができます。
  • オブジェクトのサイズを追跡する必要があるときに、マップのサイズを簡単に取得できます。

例:

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"

他のオブジェクトから参照されていないキーをガベージコレクションする場合は、マップの代わりにWeakMapを使用することを検討してください



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

これは問題ありませんが、配列オブジェクトのすべてのプロパティを反復処理します。プロパティmyArray.one、myArray.twoのみを反復処理する場合は、次のようにします

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

これで、myArray ["one"]によって両方にアクセスでき、これらのプロパティを通じてのみ反復できます。


あなたの例ではタイプミスの数を数えましたか?:-) maArray、忘れられた閉じた ')' ...
Brian Haak

例をありがとう。私たちは団結できたArrayObjectしてでのみ動作Object木!素晴らしい洞察!作るのにとても便利ですObject.getOwnPropertyNames(obj/array)
Brian Haak 14

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

            }
        };

}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.