はい、or=
or?=
演算子を使用して割り当てることができるのは、array[y.ambum]
初期化されていない場合のみです。したがって、1 つのループのみを使用します。ところで、array
変数がオブジェクトであることは少し混乱していると思います。代わりに CoffeeScript ループを使用してこれをコーディングする別の方法reduce
は次のとおりです。
albums = {}
for {album, name, mp3} in tracks
(albums[album] or= []).push {name, mp3}
トラックのプロパティを一度に取得するために、分割を使用していることに注意してください。
または、を使用する場合reduce
:
albums = tracks.reduce (albums, {album, name, mp3}) ->
(albums[album] or= []).push {name, mp3}
albums
, {}
しかし、CS-loop バージョンの方が読みやすいと思います :)
ボーナス トラック (しゃれた意図): Underscore.js を使用している場合は、 を使用することを強くお勧めしますgroupBy
。これは、まさにこの種のグループ化ジョブを実行します。
albums = _.groupBy tracks, (track) -> track.album
の各アルバム名のトラックalbums
が「完全な」トラックになることに注意してください (名前と mp3 プロパティだけではありません)。
更新:パフォーマンスに関するコメント:「効率的に」何かをするように頼まれたとき、私はそれを可能な限り最も直接的でクリーンな方法で行うと解釈します(コードを読むときのプログラマーの効率について考えています); しかし、多くの人は明確に効率をパフォーマンスに関連付けます。
パフォーマンスについては、これら 3 つのソリューションはすべて O(n) であり、n はトラックの数であり、複雑です。どちらも他のものよりひどく悪いわけではありません。
生のfor
ループは、同等の高次の兄弟forEach
である、 などよりも最新の JS エンジンで高速に実行されるようreduce
です(これは非常に悲しいことです :(...)。したがって、最初のバージョンは 2 番目のバージョンよりも高速に実行されるはずです。
Underscore バージョンの場合、Underscore は生のループの代わりに高次関数を多くfor
使用することで知られているため、予測は行いませんが、同時に、そのバージョンはトラックごとに新しいオブジェクトを作成しません。 .
いずれにせよ、パフォーマンスは向上するが読みにくいソリューションにソリューションを変更する前に、必ずコードをプロファイリングする必要があります。その特定のループがボトルネックであることに気付き、それをベンチマークするための適切なデータ セットがある場合、jsPerfは非常に便利です:)