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

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

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

Lodashは、JavaScriptのユーティリティライブラリ。Underscoreの派生ライブラリで、配列・オブジェクトの操作に便利です。また、コードの可読性も高めることができます。

JavaScript

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

Q&A

解決済

3回答

2007閲覧

js ループ処理の最適化

tommyTeratail

総合スコア31

Lodash

Lodashは、JavaScriptのユーティリティライブラリ。Underscoreの派生ライブラリで、配列・オブジェクトの操作に便利です。また、コードの可読性も高めることができます。

JavaScript

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

0グッド

1クリップ

投稿2018/02/06 08:27

編集2018/02/06 10:44

下記コードを 最適化したい

課題

const list = [];return list; が見苦しい

_.map() をうまく利用したいが方法が思いつかない

javascript

1const list = { 2 'sports': [ 3 { 4 identify: 'soccer', 5 name: 'サッカー', 6 }, 7 { 8 identify: 'baseball', 9 name: '野球', 10 }, 11 ], 12 'nature': [ 13 { 14 identify: 'animal', 15 name: '動物', 16 }, 17 { 18 identify: 'flower', 19 name: '花', 20 }, 21 ], 22}; 23 24const groups = [ 25 {identify:'sports', id: 1}, 26 {identify:'nature', id: 2}, 27]; 28 29const make = (tmpList, groups) => { 30 const list = []; 31 _.forEach(groups, group => { 32 _.forEach(tmpList[group.identify], v => { 33 v['group_id'] = group.id; 34 list.push(v); 35 }); 36 }); 37 38 return list; 39}; 40 41console.log( 42 make(list, groups) 43);

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

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

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

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

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

defghi1977

2018/02/06 09:14

引数tmpList, groupsの形状と, 関数makeがどのような結果をもたらす(もたらしたい)のかについて記述を追加して下さい.
tommyTeratail

2018/02/06 10:18

データを準備しました。 動作は期待通りですが makeが見苦しいのでアドバイスが欲しいです
turbgraphics200

2018/02/06 10:31 編集

ほんとに期待通りなのでしょうか?、提示されたコードを実行すると返されるlistのgroup_idがすべて2になるのですが。
tommyTeratail

2018/02/06 10:33

おっしゃる通りですね、 バグです
guest

回答3

0

修正後のコードも、その場しのぎの修正のような気がしてならないのですが、makeが返すlistの値として期待するものは(可読性度外視, Chrome/Firefoxのみ)

js

1const make = (t, g) => g.reduce((a, {identify, id}) => !t[identify].map(i => a[a.push({...i}) - 1].group_id = id) || a, []);

の結果だと思われますが。

投稿2018/02/06 11:30

編集2018/02/06 11:37
turbgraphics200

総合スコア4267

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

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

tommyTeratail

2018/02/06 12:34

修正後のコードは、正しいです 回答ありがとうございます。 期待通りの動作です。 魔術のようなコードですね。 私には難しかったです
guest

0

ベストアンサー

2次元配列にしてからflattenで1次元配列に叩き落とすか、
reduceで2次元配列→1次元配列に戻しながら格納するかの二択ですね。

こんな感じでいかが?

JavaScript

1const make = (tmpList, groups) => 2 _(tmpList) 3 .map(tmp => 4 _.map(groups, group => ({...tmp, id: group.id})) 5 ) 6 .flatten() 7 .values() 8 9const users = [ 10 { user: 'barney', age: 36, active: true }, 11 { user: 'fred', age: 40, active: false }, 12 { user: 'travis', age: 37, active: true} 13]; 14const ids = [ 15 { id: 123 }, 16 { id: 234 } 17]; 18console.log(make(users, ids)); 19// いい感じにでました

【おまけ】

reduce使うルートならネイティブJSでも出来そうなのでやりました。

JavaScript

1const make = (tmpList, groups) => 2 tmpList 3 .map(tmp => groups.map(group => ({...tmp, id: group.id}))) 4 .reduce((arr, items) => { 5 items.forEach(it => { arr.push(it) }); 6 return arr; 7 }, []) 8 9const users = [ 10 { user: 'barney', age: 36, active: true }, 11 { user: 'fred', age: 40, active: false }, 12 { user: 'travis', age: 37, active: true} 13]; 14const ids = [ 15 { id: 123 }, 16 { id: 234 } 17]; 18console.log(make(users, ids)); 19// こちらもいい感じの結果に

【追記】 グループ分けしたオブジェクトへの対応版

条件変わってますので再度考え直してみます。
まぁ、オブジェクトはtoPairsを使って配列にしてしまえば消化試合です。

キーに引っかかるグループが存在しなかった場合を考慮して、
存在しないグループは一度filterで消し飛ばすというガードも組み込みました。

JavaScript

1const list = { 2 'sports': [ 3 {identify: 'soccer', name: 'サッカー'}, 4 {identify: 'baseball', name: '野球'} 5 ], 6 'nature': [ 7 {identify: 'animal', name: '動物'}, 8 {identify: 'flower', name: '花'} 9 ] 10}; 11const groups = [ 12 {identify:'sports', id: 1}, 13 {identify:'nature', id: 2}, 14]; 15 16const make = (tmpList, groups) => 17 _(tmpList) 18 .toPairs() 19 .filter(([gname]) => _.find(groups, group => group.identify === gname)) 20 .map(([gname, items]) => { 21 const group = _.find(groups, group => group.identify === gname); 22 return _.map(items, it => ({...it, group_id: group.id})); 23 }) 24 .flatten() 25 .value() 26 27result = make(list, groups)

https://codepen.io/travist/full/jrBjBz/にコピペすればちゃんと表示されることがわかります。
結果:

JSON

1[ 2 { 3 "identify": "soccer", 4 "name": "サッカー", 5 "group_id": 1 6 }, 7 { 8 "identify": "baseball", 9 "name": "野球", 10 "group_id": 1 11 }, 12 { 13 "identify": "animal", 14 "name": "動物", 15 "group_id": 2 16 }, 17 { 18 "identify": "flower", 19 "name": "花", 20 "group_id": 2 21 } 22]

投稿2018/02/06 09:26

編集2018/02/06 11:10
miyabi-sun

総合スコア21158

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

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

miyabi-sun

2018/02/06 09:44

うぅ、いけると思って未テストだったから動かなかった・・・ 修正して動作確認しました
miyabi-sun

2018/02/06 09:47

ちな、このコードだと名前がbarney、fred、fravisのデータが2件ずつ出来てしまいますが大丈夫ですか? しかもID重複してるので正常なデータには思えませんが… tmpListだけに単なるテストデータ?
tommyTeratail

2018/02/06 10:48

提示していただいたコードが、理想の形式です
miyabi-sun

2018/02/06 10:54

修正後コードだとこの手は使えないですね、 対応版のコード作るのでちょっと待ってくださいね
tommyTeratail

2018/02/06 12:44

回答ありがとうございます 途中で条件が変わってしまいすみません。 検証が甘いコードをはっていました。 何度も回答本当にありがとうございます 期待通りの回答です。 pushしてreturnするのは、jsらしくない感じと思っていました。 新しい考え方を得た気がします toPairsばっちりですね
tommyTeratail

2018/02/06 12:48

おまけのほうもありがとうございます
guest

0

回答者はLodashに詳しくありません.


JavaScriptの標準APIを使うとこんな感じでしょうか?
tmpList内のオブジェクトが出力結果配列内に何度も現れるのが気になりますが.

JavaScript

1const tmpList = [{v: 1}, {v: 2}]; 2const groups = [{id: 1}, {id: 2}]; 3const make = (tmpList, groups) => groups.reduce( 4 (prev, curr) => prev.concat(...tmpList.map(v => (v.id = curr.id, v))), //vをクローンしたほうが良いのかも 5 [] 6); 7console.log(make(tmpList, groups));

投稿2018/02/06 09:43

defghi1977

総合スコア4756

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

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

defghi1977

2018/02/06 10:27

LodashのforEachはオブジェクトを受けるので, これだと駄目だね
tommyTeratail

2018/02/06 12:37

回答ありがとうございます。 > vをクローンしたほうが良いのかも 可能であれば理由がしりたいです。
defghi1977

2018/02/06 13:08

誤った前提でのコード・コメントなので, お気になさらず. (言外に元のコードバグってね?という意図がありました)
tommyTeratail

2018/02/06 13:13

質問したコードが検証甘かったのでご迷惑おかけしました。 協力ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問