JavaScriptの連想配列のキーとして整数を使用する


102

新しいJavaScript配列を作成し、整数をキーとして使用すると、その配列の整数までの各要素が未定義として作成されます。

例えば:

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

2298 undefinedと1つの 'Some string'を出力します。

JavaScriptで整数の代わりに文字列として2300を使用するにはどうすればよいですか、または2299空のインデックスをインスタンス化しないようにするにはどうすればよいですか?

回答:


128

人々が言っ​​ているように、オブジェクトを使用してください。ただし、整数キーは使用できないことに注意してください。JavaScriptは整数を文字列に変換します。次の出力20は未定義ではありません。

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

12
+1これは配列にも当てはまることに注意してください!stackoverflow.com/questions/1450957/…を
bobince

1
@bobince:内部的には確かです。ただし、論理的には、配列には整数の「キー」があります。
オービットのライトネスレース

1
キーとして整数を使用すると、配列の長さが変わることに注意してください。代わりに確実にObjectを使用してください。私はキーとしてfacebook idを使用したかっただけで、JSON.stringifyがマシンをクラッシュさせました;)
Krystian

2
@LightnessRacesinOrbit内部の詳細はまだ漏れ、あなたを噛む可能性があります。今日私が遭遇したもののこの簡略化されたバージョンを参照してください:jsfiddle.net/cincodenada/pseujLex/2削減する不自然に見えるかもしれませんが、大きなスクリプトの意味のある部分でした(そして、CoffeeScript では少し不自然です:jsfiddle.net/ cincodenada / oojr7Ltn / 2)。この実装の詳細のように見えるため、今日はかなりのバグハンティングが必要です。
cincodenada 14

1
:少し非整数のためのノート 0.25.25同じ文字列を決意"0.25"。あなたが小数のキーを使用しているのであれば、あなたは数値的に設定したキーのプロパティ取得することができます0.25使用して0.25.25"0.25"ではありません".25"
Sandy Gifford、2015

34

あなたはオブジェクトを使うことができます:

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

16
それでも文字列にキャストされます。
drew010

1
@ drew010はい、JavaScriptのオブジェクトでは、文字列のみを使用してインデックスを作成できます。
ピティコ

22

人々が言うように、JavaScriptは数値の文字列を整数に変換するため、連想配列で直接使用することはできませんが、オブジェクトは私と同じように機能します。

オブジェクトを作成できます:

var object = {};

配列が機能するように値を追加します。

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

これはあなたに与えるでしょう:

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

その後、キーを取得する他の言語の配列のようにそれにアクセスできます:

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

私はテストして動作します。


17

ユースケースがデータをコレクションに格納する場合、ECMAScript 6Mapタイプを提供します。

初期化は重いだけです。

次に例を示します。

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

結果:

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

11

他の回答をまとめる:

オブジェクト

var test = {};

数値を新しいプロパティのキーとして使用すると、数値は文字列に変わります。

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

同じ数値を使用してプロパティの値にアクセスすると、数値は再び文字列に変換されます。

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

ただし、オブジェクトからキーを取得する場合、キーは数値に戻されません。

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

地図

ECMAScript 6では、マップオブジェクト(ドキュメントオブジェクトとの比較)を使用できます。コードがローカルで解釈されることを意図している場合、またはECMAScript 6の互換性テーブルが目的に合わせて十分に緑色に見える場合は、マップの使用を検討してください。

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

良くも悪くも型変換は行われません:

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

4

配列の代わりにオブジェクトを使用します。JavaScriptの配列は連想配列ではありません。それらは、名前が整数のように見えるプロパティに関連付けられた魔法を持つオブジェクトです。従来の配列のような構造としてそれらを使用していない場合、その魔法はあなたが望むものではありません。

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

1
それら連想配列にすることができますが、名前付きプロパティを設定できるオブジェクトでもあるからです。しかし、これは物事を途方もなく混乱させるだけなので、そうです、オブジェクトは使用する方がはるかに優れています。
Graza

配列を連想Grazaにすることはできません。配列でキーを使用してからそれらを反復しようとすると、配列のすべてのデフォルトのメソッドとプロパティを反復処理していることに気付くでしょう->あまり望ましくない。
Swizec Teller 2010

@Swizec-正確に私が「途方もなく混乱する」と言った理由。あなたはでき連想配列として配列を使用する-名前/値ペアとしてですが、あなたはそれらを反復処理したくないでしょう!(私は単に専門性を指摘していましたが、間違いなく私が推奨するものではありません)
Graza

はい。ただし、反復するときに特定の順序ではない(つまり、順序は保証されない)ため、番号付けのポイントになるので、混乱するだけではありません。
Julix

3

配列ではなくオブジェクトを使用してみてください。

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

3
これは間違いなく進むべき道です。この方法では、単一の文字列を格納するために2300エントリの長い配列を作成しません。
クリスティアン

2
@Krystian JS配列は偽の配列です。実行するvar a = []; a[Math.pow(2, 30)] = 'hello';と、ブラウザ/メモリの使用量がギガバイトを超えて表示されることa.lengthはありませんが、1073741824であることがわかります。VMは、他のデータ構造を使用していくつかの「配列」を明確に格納します。それらは十分にまばらです。
アンディ

2

プロパティ名が整数の場合、連想配列プロパティの値を取得します。

プロパティ名が整数である連想配列から始めます。

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

アイテムを配列にプッシュします。

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

配列をループして、プロパティ値で何かを行います。

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

コンソール出力は次のようになります。

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

ご覧のとおり、連想配列の制限を回避し、プロパティ名を整数にすることができます。

注:この例の連想配列は、Dictionary <string、string> []オブジェクトをシリアル化した場合のJSONコンテンツです。


0

配列ではなく、キーとして整数を使用したオブジェクトを使用します。


0

時々、キーにプレフィックスを使用します。例えば:

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

obj = {};

obj[key] = val;

これで、アクセスに問題はありません。

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