連想配列オブジェクトのJavascript foreachループ


182

for-eachループがJavaScriptの連想配列オブジェクトを繰り返し処理しないのはなぜですか?

// defining an array
var array = [];

// assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";

// expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

編集:jQuery each()が役立つ可能性があります:https//api.jquery.com/jQuery.each/


1
配列を作成し、それをマップとして使用します。代わりにプレーンオブジェクトが必要なようです。
Jon

4
associative arraysJSのようなものはありません。それは単純な配列またはオブジェクトのいずれかです。数値以外のプロパティをに追加することを妨げるものは何Arrayもありませんが、それはできません。associative特に、lengthプロパティはこれらのプロパティを自動カウントしません。
raina77ow 2013

3
re:JSには連想配列などはありません。-別の言い方をすれば、JavaScriptは「連想配列」という名前の代わりに「オブジェクト」という名前を使用します。ただし、「。length」プロパティはありません。
ジェシーチザム2014年

回答:


315

.lengthプロパティは、数値インデックス(キー)を持つプロパティを追跡します。キーに文字列を使用しています。

あなたはこれを行うことができます:

var arr_jq_TabContents = {}; // no need for an array

arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;

for (var key in arr_jq_TabContents) {
    console.log(arr_jq_TabContents[key]);
}

安全のために、そのようなループでは、どのプロパティも継承の予期しない結果にならないようにすることをお勧めします。

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}

編集Object.keys()関数は最新のブラウザやNodeなどで使用できることに注意してください。この関数はオブジェクトの「独自の」キーを配列として返します。

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);

に渡されるコールバック関数.forEach()は、各キーとによって返される配列内のキーのインデックスで呼び出されObject.keys()ます。また、関数の反復処理に使用される配列も渡されますが、その配列は実際には役に立ちません。元のオブジェクトが必要です。名前で直接アクセスできますが、(私の意見では)明示的に渡す方が少しいいです。これは、2番目の引数を.forEach()元のオブジェクトに渡すことによって行われthisます。元のオブジェクトは、コールバック内でバインドされます。(これが以下のコメントで指摘されているのを見ただけです。)


これはなにvar arr_jq_TabContents = {};
つまり、

1
@Ultraは空のオブジェクトリテラルです。これは、変数が新しい空のオブジェクトへの参照で初期化されることを意味します。
とがった2013

@Ultraでは、JavaScriptインスタンスのように使用していないため、Arrayインスタンスは必要ありません。JavaScriptには、他の一部の言語のような「連想配列」はありません。
とがった2013

1
割り当ての違いは何である[]とは{}?異なるプロトタイプだけですか?
SoonDead 2014年

8
:代わりにhasOwnPropertyをを使用するには、使用してオブジェクトのキーを反復処理するためにすべての現代のWebブラウザで可能なはず Object.keys(arr_jq_TabContents).forEach( function(key) { ... } );
グレゴリー・ベル

80

これは非常に単純なアプローチです。利点は、キーも取得できることです。

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}

ES6の場合:

array.forEach(value => {
  console.log(value)
})  

ES6の場合:(値が必要な場合は、インデックスと配列自体)

array.forEach((value, index, self) => {
  console.log(value, index, self)
})  

12
var存在しないスコープを示唆するループで使用しないでください。varループの前またはループで使用しletます。
15

2
@ceving、ループでvarを使用しない理由について詳しく説明できますか?私はC ++ / PHPの出身ですが、これは理解できません。スコーピングはループ内に存在しますが、一時的なものであるため、どういう意味かわかりません。
Dennis

6
@Dennisほとんどの言語では、forループ内の変数宣言により、ループの本体に限定されたスコープが生成されforます。ただし、JavaScript varでは、forループで記述した場合でも、によって宣言された変数は常にグローバル関数です。こちらをご覧ください:davidwalsh.name/for-and-against-let
16

1
それ自体はメモリリークではありませんが、間違いなく「メモリスピル」です。varJavaScriptでは、ループが完了した後でもメモリ内に変数が作成されます。
ahnbizcad 2016

「var」の使用に関するこれらのコメントの要点は、「let」を一般的に、具体的にはループで使用することです。理由は上記で説明されていますが、要約すると「var」がスコープを作成するため、グローバルスコープが作成されます。
DeeZone、

6

簡単な例はすでにいくつかありますが、質問の言い方から、おそらくPHPのバックグラウンドに由来し、JavaScriptが同じように機能することを期待していることに気づきました。PHP arrayはJavaScriptとは大きく異なりますArray

PHPでは、連想配列は数値でインデックス付けされた配列が実行できるほとんどのことを実行できます(array_*関数は機能し、実行できますcount())。単に配列を作成し、数値ではなく文字列インデックスへの割り当てを開始します。

JavaScriptでは、すべてがオブジェクト(プリミティブを除く:文字列、数値、ブール値)であり、配列は数値インデックスを持つ特定の実装です。配列にプッシュものはその効果になるlength、とArrayメソッドを使用して上で反復することができます(mapforEachreducefilterfind、など)すべてが対象であるための何かがあなたに行うことをしかし、あなたは、いつでも自由に簡単にアサイン性質です任意のオブジェクト。角かっこ表記は、プロパティにアクセスするためのもう1つの方法なので、あなたの場合:

array['Main'] = 'Main Page';

実際には次と同等です:

array.Main = 'Main Page';

あなたの説明から、私の連想配列は「連想配列」が必要だと思いますが、JavaScriptの場合、これはオブジェクトをハッシュマップとして使用する単純なケースです。また、私はそれが例であることを知っていますが、変数のタイプのみを説明する意味のない名前(例:)arrayと、それが含むべきもの(例:)に基づく名前は避けてくださいpages。単純なオブジェクトには、反復処理を行う直接的な方法があまりないため、最初にObjectメソッドを使用して配列に変換することがよくあります(Object.keysこの場合はentriesvalues現在いくつかのブラウザーに追加されており、ループすることができます)。

// assigning values to corresponding keys
const pages = {
  Main: 'Main page',
  Guide: 'Guide page',
  Articles: 'Articles page',
  Forum: 'Forum board',
};

Object.keys(pages).forEach((page) => console.log(page));

4

arr_jq_TabContents[key] 配列は0インデックス形式と見なされます。


4

連想配列を汎用のオブジェクト型として使用する簡単な方法を次に示します。

Object.prototype.forEach = function(cb){
   if(this instanceof Array) return this.forEach(cb);
   let self = this;
   Object.getOwnPropertyNames(this).forEach(
      (k)=>{ cb.call(self, self[k], k); }
   );
};

Object({a:1,b:2,c:3}).forEach((value, key)=>{ 
    console.log(`key/value pair: ${key}/${value}`);
});



1

これはほとんどの場合(本質的に)正しくありません。

var array = [];
array["Main"] = "Main page";

これにより、という名前の配列に非要素プロパティが作成されますMain。配列はオブジェクトですが、通常は要素以外のプロパティを作成する必要はありません。

arrayこれらの名前でインデックスを作成する場合は、通常Map、配列ではなくまたはオブジェクトを使用します。

Map私は電話するよ(ES2015 +)、map私は創造だから:

let map = new Map();
map.set("Main", "Main page");

あなたは、そのからイテレータを使用して、それを繰り返すvalueskeysまたはentries例えば、方法:

for (const value of map.values()) {
    // Here, `value` will be `"Main page"`, etc.
}

私が創造的に呼び出すプレーンオブジェクトを使用しますobj

let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`

あなたはその後、使用してその内容を反復処理したいObject.keysObject.valuesまたはObject.entries例えば、:

for (const value of Object.values(proches_X)) {
    // Here, `value` will be `"Main page"`, etc.
}

0

var obj = {
  no: ["no", 32],
  nt: ["no", 32],
  nf: ["no", 32, 90]
};

count = -1; // which must be static value
for (i in obj) {
  count++;
  if (obj.hasOwnProperty(i)) {
    console.log(obj[i][count])
  };
};

このコードでは、arrayが含まれているため、配列の呼び出し値にブラケットメソッドを使用しましたが、簡単に言うと、変数iがプロパティのキーを持ち、ループで、関連付けられた配列の両方の値と呼ばれるループを持っています

完璧な方法、興味があれば、


配列をループするのではなく、キーに配列を持つオブジェクトをループするのです。質問を読んで例を見てください。
ペドロホアキン

0

あなたはこれを行うことができます

var array = [];

// assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";


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