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

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

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

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

Q&A

解決済

4回答

3079閲覧

Javascriptで副作用を用いずコレクション(配列)をオブジェクトに変換する方法

hojo

総合スコア195

JavaScript

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

0グッド

1クリップ

投稿2016/07/05 23:32

編集2016/07/06 00:21

javascript

1var ary = [{name:'hoge', value:1}, {name:'fuga', value:2}]; 2 3var obj = {}; 4ary.forEach(function(v){ obj[v.name] = v.value; });

上記のコードを副作用を用いずにobjを返すにはどうすれば良いですか?reduceを使えば可能かな?と思ったのですが、上記より複雑になってしまいました。

つまり下記のような書き方で同じ結果を取得したいということです。
(xxxは何らかのメソッド。...は無名関数の中身を省略)

javascript

1var obj = ary.xxx(function(){ ... });

もっともシンプルな手法としては、やはり提示した副作用を用いる書き方になるのでしょうか?宜しくお願いします。

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

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

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

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

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

harashow1701

2016/07/06 00:10

配列をオブジェクトにする方法というタイトルが不適切です。修正して下さい。
hojo

2016/07/06 00:21

これでいいですか?ダメだったら適切な名前を教えてください。
guest

回答4

0

ベストアンサー

ary.forEach の第一引数で定義されている無名関数が、外のオブジェクト(obj)に対して直接作用しています。これを「副作用」と表現しています。

Array.prototype.reduce を使えば副作用なしのコードになると思うのですが、どの辺りが「複雑」と感じられたのでしょうか。

JavaScript

1'use strict'; 2var ary = [{name:'hoge', value:1}, {name:'fuga', value:2}]; 3 4var obj = ary.reduce(function (before, current) { 5 before[current.name] = current.value; 6 7 return before; 8}, {}); 9 10console.log(obj); // {hoge: 1, fuga: 2}

Re: hojo さん

投稿2016/07/06 02:24

編集2016/07/06 02:27
think49

総合スコア18156

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

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

hojo

2016/07/06 05:08 編集

reduceの第二引数でbeforeの初期値にオブジェクトを渡すという発想が出てきませんでした!!これを求めていました!
guest

0

副作用を用いるというのは、どういう意味でしょうか?用いたくないなら、用いなければ良いだけの話かと思います。

投稿2016/07/05 23:33

harashow1701

総合スコア854

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

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

hojo

2016/07/05 23:37 編集

ary.forEachの第一引数で定義されている無名関数が、外のオブジェクト(obj)に対して直接作用しています。これを「副作用」と表現しています。可能であれば、ary.forEachに変わるメソッドがobjを返す式にしたいということです。```var obj = ary.xxx(function(){ ...});```の式でobjに求めている値が入るようにしたいということです。
guest

0

Array.prototype.reduceよりシンプルに書くことを優先するとなると、コレクション操作系で有名なloadshというライブラリがありますが、_.keyByがこのような動作をします(ドキュメント)。

これのソースを確認してみると、引数で渡したオブジェクトに代入していく方式でした(GitHub)。

投稿2016/07/06 00:02

maisumakun

総合スコア145064

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

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

hojo

2016/07/06 00:32 編集

なるほど、_.keyByなんてあったんですね!若干の妥協はありますが、既にlodashは導入していたのでこちらを利用させていただきます!
guest

0

どうしてもArrayのオブジェクトが持つメソッドを使った戻り値でobjを受け取りたいのなら強引に自作するという方法もあります。しかし、この手法は連想配列の配列を持つArrayにしかまともに動作しないのに、全てのArrayで呼び出すことができるので、動作がおかしくなる可能性はあります。

Javascript

1// ArrayにconvertDictArrayToDictというメソッドを追加する 2Object.defineProperty(Array.prototype, 'convertDictArrayToDict', { 3 enumerable: false, 4 value: function (key, val) { 5 var ret = {}; 6 for(var index in this) { 7 var map = this[index]; 8 ret[map[key]] = map[val]; 9 } 10 return ret; 11 } 12}); 13 14var ary = [{name:'hoge', value:1}, {name:'fuga', value:2}]; 15var obj = {}; 16obj = ary.convertDictArrayToDict("name", "value"); // 呼び出して使う 17 18var ary2 = [1, 2, 3, 4, 5]; 19ary2.convertDictArrayToDict("a", "b"); // ただの配列にもこのメソッドは存在するが、当然おかしな動作になる

素直にfunctionを作って、そちらを使うべきだと思います。

Javascript

1function convertDictArrayToDict(ary, key, val) { 2 var ret = {}; 3 for(var index in ary) { 4 var map = ary[index]; 5 ret[map[key]] = map[val]; 6 } 7 return ret; 8} 9 10var ary = [{name:'hoge', value:1}, {name:'fuga', value:2}]; 11var obj = {}; 12obj = convertDictArrayToDict(ary, "name", "value");

投稿2016/07/05 23:58

masaya_ohashi

総合スコア9206

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

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

hojo

2016/07/06 00:31

素直にfunctionを作うのが良い、確かにその通りだと思いました。もっとも適切な回答と思われました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問