質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

1297閲覧

javascriptで連想配列がforeach出来ない

tesopgmh

総合スコア146

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2017/12/11 07:32

「a:1,b:2,c:3」こういった文字列を連想配列に変換する関数hugaを作ったのですが
連想配列に変換した値をforEachするとなにも起きません

期待する結果
1
2
3

実際の結果
<なにもない>

valsをconsole.dirすると

a: "1"
b: "2"
c: "3"

となっているので連想配列への変換はうまくいっているようなのですが
なぜforEach内のプログラムが実行されないのでしょうか

分かる方お教えくださいませ

var vals = huga('a:1,b:2,c:3'); vals.forEach(function(value,key){ console.log(value); }); function huga(str){ arr = []; arr2 = []; arr = str.split(','); var i = 1; arr.forEach(function(value,key){ var tmp_arr = []; tmp_arr = value.split(':'); key = tmp_arr[0]; value = tmp_arr[1]; arr2[key] = value; }); return arr2; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

Array.prototype.forEach数値プロパティのみ参照するようになっているので、配列に無理やりarr['a'] = 'b';のようなものを代入しても、それは単に無視されます。

普通のオブジェクトに入れて、Object.keysでキーリストを取得する、あるいはfor-inを使う、などの手段が必要です。

投稿2017/12/11 07:51

maisumakun

総合スコア145123

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tesopgmh

2017/12/12 01:31

なるほど!forEachは数値しか見てくれないんですね Javascriptは素晴らしい言語ですがたまに他の言語で当たり前に出来ることが出来なくてビックリすることがあります
tesopgmh

2017/12/12 01:36

for-inでうまくいきました!ありがとうございます!
guest

0

数値添字配列

JavaScriptの配列は数値添字配列であり、文字列添字配列に対応していないからです。
文字列添字配列が必要な場合は、次のいずれかを使用する事になります。

  • オブジェクト初期化子({})
  • Object.create(null)
  • new Map

new Map

Map には Map.prototype.forEach があるので、比較的扱いやすいといえます。

JavaScript

1'use strict'; 2function foo (string) { 3 var array = string.split(','); 4 5 for (var i = 0, len = array.length; i < len; ++i) { 6 array[i] = array[i].split(':'); 7 } 8 9 return new Map(array); 10} 11 12var map = foo('a:1,b:2,c:3'); 13 14console.log(map.get('a')); // 1 15console.log(JSON.stringify([...map.entries()])); // [["a","1"],["b","2"],["c","3"]] 16 17map.forEach((value, key) => console.log(value, key));

Object.create(null)

Object.create(null){} とほぼ等価ですが、プロトタイプ上にオブジェクトが存在しない為、__proto__ 等の規定値となる名前もキー名に出来るメリットがあります。

JavaScript

1'use strict'; 2function foo2 (string) { 3 var object = Object.create(null); 4 5 for (var i = 0, array = string.split(','), len = array.length, entry; i < len; ++i) { 6 entry = array[i].split(':'); 7 object[entry[0]] = entry[1]; 8 } 9 10 return object; 11} 12 13var object = foo2('a:1,b:2,c:3'); 14 15console.log(object.a); // 1 16Object.keys(object).forEach(key => console.log(key, object[key]));

Re: tesopgmh さん

投稿2017/12/11 07:51

編集2017/12/11 08:45
think49

総合スコア18156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tesopgmh

2017/12/12 01:33

文字列添字配列に対応していないというのはどういうことですか?普通に使えますけど?? 歴史的に昔はそうであったということですか?ググってみたのですが出てきませんでした mapの使い方ありがとうございます!!
think49

2017/12/12 03:35 編集

例えば、var array = []; を定義した場合、array.a = 1; で要素を増やしても array.length は増えませんし、array.forEach で走査することも出来ません。つまり、文字列をキーにしても配列独自の機能が使えません。 for-inやObject.keysが有効なのは、配列がオブジェクトでもあり、オブジェクトのプロパティ列挙機能でキーの列挙を代用しているためです。 しかし、ただのオブジェクトとしての扱いとなるため、定義順で列挙される保証がなく、lengthのように配列の要素数を数える機能もありません(Object.keys(array).lengthで代用可)。 文字列をキーにする限りでは、{} と [] はほぼ等価です。 また、array.lengthのような予約済みのプロパティに任意の文字列値を与えることも不可能であり、その点では、Object.create(null) が勝ります。 諸々の問題を全てを解決したのが new Map となります。
guest

0

上記を御覧ください、ArrayにはArray.prototype.forEachがありますが、
ObjectにはObject.prototype.forEachなるメソッドは存在しません。
というわけで無いものはないのだ!

どうすんねん?

上記のメソッドを経由して使いましょう。
ES5対応のObject.keysが第一選択肢となります。
次点はfor...of構文ですね、ただしこちらは殆どのブラウザに採用されているとはいえES2015なのでIE11では使えない事に注意してください。
本来ならばvaluesやentitiesが便利なのですがES2015専用だし対応ブラウザはChromeくらいしかありません。

質問文からはこうすれば通るかと思います。

JavaScript

1var vals = huga('a:1,b:2,c:3'); 2Object 3 .keys(vals) 4 .forEach(function(key){ 5 console.log(value); 6 });

【おまけ】普通のオブジェクトをつくる

オブジェクトじゃないじゃないか!
こっちも私の勝手に作っちゃうんだからね!!

JavaScript

1function huga (str) { 2 return str 3 .split(',') 4 .map(function(it){ return it.split(':'); }) 5 .reduce(function(obj, it){ 6 obj[it[0]] = it[1]; 7 return obj; 8 }, {}); 9} 10var vals = huga('a:1,b:2,c:3'); 11console.log(vals); 12// Object { a: "1", b: "2", c: "3" }

これなら私の回答文のはじめの状態から使えると思うから試してみてね。

投稿2017/12/11 08:12

編集2017/12/11 08:18
miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tesopgmh

2017/12/12 01:35

丁寧にありがとうございます!こんな書き方もあるんですね Javascriptは同じ処理でもいろいろな関数や書き方が混在していてとてもユニークですね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問