LoginSignup
1
0

More than 5 years have passed since last update.

forEachを使わずフラットなデータをツリーデータにする

Last updated at Posted at 2019-04-07

なんとなくArray.prototype.forEachやjQueryのeachを使って再帰関数を回していたのですが、「JavaScript で forEach を使うのは最終手段」という記事を読み、少し考えを改めてみようと思いました。

しかしparent_idというプロパティを持つフラットなデータを読み込み、それをツリー型にしてみたいと思った時、あれ?と考え込みました。
うーん、forEachつかわず再帰処理させつつデータを作り直すってどうやるんだ・・・

とりあえず何も考えず書いたコード
let func = (obj) => {
    obj.items = Object.assign([], master_categories.filter(category => 
        category.parent_id === obj.category_id))
    obj.items.forEach(func)
}
let categories = Object.assign([], master_categories.filter(category => !category.parent_id))
categories.forEach(func)
//読みにくいかもですが、filter()は実体参照するのでassign()でオブジェクトを複製してます

Array.prototype.mapを使う

forEachよりはマシなのだろうか?
本来はこんな使い方をする関数ではなさそうですが、ひとまずはperlっぽくmapを使うことに。

let func = (obj) => {
    let robj = Object.assign({}, obj)
    robj.items = master_categories.filter(category =>
        category.parent_id && category.parent_id === robj.category_id).map(func)
    return robj
}
let categories = master_categories.filter(category => !category.parent_id).map(func)

もっと賢いやり方がありそうですが、ひとまずこれで妥協することに。

追記

一応それっぽいですが、なにか優位だと言える証拠をみつけたかったのでGoogle(他力)にすがってみました。
参考:JavaScript — Map vs. ForEach(codeburst.io)
このサイトの検証結果ではforEachmapより70%も遅いという結果がでたそうです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0