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

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

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

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

JavaScript

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

Q&A

解決済

5回答

4301閲覧

[JavaScript] 繰り返し処理でforEachを避けたい

gano

総合スコア39

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

JavaScript

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

2グッド

2クリップ

投稿2020/05/04 02:26

背景

以下の記事を読み、可読性含めforEachを避けるようにしようと感じた。

JavaScript で forEach を使うのは最終手段

早速 forEach を避けられない

連想配列の各値に同じ計算(例えば3倍など)をして、
計算した結果を新しいobjectとして返す。

JavaScript

1 2const obj = { 3 a: 3, 4 b: 4, 5 c: 5 6}; 7 8const calculatedObj = {}; 9 10Object.keys(obj).forEach((key) => { 11 calculatedObj(key) = obj[key] * 3; 12} 13 14console.log(calculatedObj); // { a: 9, b: 12, c: 15}

質問

こういったケースは頻繁に起こりうると思いますが、forEachを使わない方法はありますでしょうか? for ... in は、Lintに弾かれてしまうので、for in 以外で考えたいと思っております。アドバイスのほどお願いいたします。

ryotarolab, umaru👍を押しています

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

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

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

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

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

kei344

2020/05/04 03:51

まだ質問が「受付中」になっていますが、だいたい出揃っていると思いますので、いったん「解決済」にされてはいかがでしょうか。また、解決されていないなら状況を質問文に追記ください。
gano

2020/05/04 04:07

ご指摘ごもっともです。各回答にコメント後、解決済みにいたします。 ありがとうございます。
guest

回答5

0

ベストアンサー

reduceを使って書けます。

javascript

1const obj = { 2 a: 3, 3 b: 4, 4 c: 5 5}; 6 7const calculatedObj = Object.keys(obj).reduce((previous, key) => { 8 previous[key] = obj[key]* 3 9 return previous; 10}, {}); 11 12console.log(calculatedObj); // { a: 9, b: 12, c: 15}

投稿2020/05/04 02:36

編集2020/05/04 02:36
70_10

総合スコア65

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

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

gano

2020/05/04 02:39

早速の回答ありがとうございます。 previous の初期値を {} にするのですね。。大変勉強になりました。
guest

0

こんにちは。2案、回答します。

1. Object.entries、Object.fromEntries および map を使う

Object.entriesで配列にして map で3倍にし、Object.fromEntries で再度オブジェクトにします。

javascript

1const calculatedObj = Object.fromEntries( 2 Object.entries(obj).map(([k, v]) => [k, 3 * v]) 3);

2. lodash の mapValues を使う

配列やオブジェクトの操作で便利なライブラリ lodash の _.mapValues を使います。

javascript

1const calculatedObj = _.mapValues(obj, v => 3 * v);

以上、参考になれば幸いです。

追記

上記の回答のうち、1つ目は、以下のサンプルと(2倍か3倍かの違いを除いて、)ほとんど同じです。

オブジェクトの変形

Object.fromEntries、逆のメソッド Object.entries()、配列操作メソッドを使用して、以下のようにオブジェクトを変形することができます。

javascript

1const object1 = { a: 1, b: 2, c: 3 }; 2 3const object2 = Object.fromEntries( 4 Object.entries(object1) 5 .map(([ key, val ]) => [ key, val * 2 ]) 6); 7 8console.log(object2); 9// { a: 2, b: 4, c: 6 }

投稿2020/05/04 02:59

編集2020/05/04 03:46
jun68ykt

総合スコア9058

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

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

gano

2020/05/04 04:15

entries, fromEntries,mapValues, いずれも知らなかったため、大変勉強になりました。様々回答頂きましたが、_.mapValues が一番見やすいなと感じています。一方で reduceを用いた時に計算をしてると一目でわかるのでreduceも良いかなと思っております。 最初の方とどちらをベストアンサーにするか迷いましたが、早い方にベストアンサーをつけさせていただきます。申し訳ありません。 大変勉強になりました、ありがとうございました。
jun68ykt

2020/05/04 04:20

どういたしまして???? 参考になれば幸いです。
guest

0

以下の記事を読み、可読性含めforEachを避けるようにしようと感じた。
JavaScript で forEach を使うのは最終手段

ご質問で示された記事の要約:

  1. Array に実装されたメソッドは全て理解して適切に使い分けてください
  2. forEach()だけだと、スパゲッティ・ソースになっちゃってる(苦言)

2.1. Arrayの処理は forEach()だけじゃなく、map()filter()reduce()もセットで覚えてほしい.
2.2. for文は読みにくいけど早いはず。

for in 以外で考えたい

敢えて読みにくい方向の for 文を回答します(for in がダメだと「ぐぬぬ…」という気分)

javascript

1var obj = { 2 a: 3, 3 b: 4, 4 c: 5 5 }, 6 keys = Object.keys(obj), 7 rslt = {}, 8 i, l, key; 9 10for( i=0, l=keys.length; i<l; ++i ) { 11 key = keys[i]; 12 rslt[key] = obj[key] * 3; 13} 14 15console.log(rslt); // { a: 9, b: 12, c: 15}

こうなると、pollyfill とか考える人のいなかった時代のコードに逆戻りです。
せっかくなので、var宣言に変えてみましたが、Object.keys() の実装っていつ頃だっけかな?と疑問も湧いてきます。

そんなわけで、参照記事の通り、map()やfilter()、reduce() を使うのが正解だと思います。

投稿2020/05/04 04:30

AkitoshiManabe

総合スコア5434

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

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

0

mapを使う方がシンプルですね

calculatedObj = {}; Object.keys(obj).map( key => calculatedObj[key] = obj[key] * 3); console.log(calculatedObj); // {a: 9, b: 12, c: 15}

投稿2020/05/04 02:43

編集2020/05/04 03:04
moya_dev

総合スコア183

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

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

gentaro

2020/05/04 02:48

破壊的変更になっており、質問文の > 計算した結果を新しいobjectとして返す。 を満たしてません。
gano

2020/05/04 04:10

回答ありがとうございます。mapを使う方法もありますね。 個人的にですが、mapは意図して配列を返す時か、Promise.allの引数として使う形で考えていたので、頭にありませんでした。
guest

0

reduceで。

js

1const calculatedObj = Object.keys( obj ).reduce( ( pre, curr ) => { 2 pre[ curr ] = obj[ curr ] * 3; 3 return pre; 4}, {} ); 5```**動くサンプル:**[https://jsfiddle.net/cjgoty4a/](https://jsfiddle.net/cjgoty4a/) 6 7--- 8 9【Array.prototype.reduce() - JavaScript | MDN10[https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)

投稿2020/05/04 02:40

kei344

総合スコア69606

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

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

kei344

2020/05/04 02:41

ああ、遅かった。
gano

2020/05/04 02:43

回答ありがとうございました。 reduceに不慣れなので、初期値の設定の部分がうまく思いつきませんでした。 70_10 さんの方が早かったのでベストアンサーは70_10さんにつけますが、感謝いたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問