オチのない日記。
Next.jsで(といってもNext固有の要素はない。)タブがいくつも出るような画面の処理を実装していて、最終的に欲しいものは色々がソートされた配列にコンポーネントが入っている(そしてそれをレンダする)、という具合の仕事をしていた。なんかもうちょっと早くできたな〜という反省。
[ <Tab bar="buzz" />, <Tab bar="buzz" />, <Tab bar="buzz" />, ]
イメージ図↑
ここでは「ジャンルごとにタブが分かれている」みたいな画面を例にして説明する。
色々がソートされているというのが厄介で、
- 全体としては大条件(ここではそう呼ぶことにする)で並んでいて、「ジャンルなし」「ジャンル設定されてる」「ジャンル設定されてたけど参照していたジャンルが消えた」みたいな感じで並んでいてほしい。
- さらに、小条件として「ジャンル設定されてる」は各ジャンルの名前で並んでいてほしいし、「ジャンルなし」「ジャンル設定されてたけど参照していたジャンルが消えた」やつはソートできる名前がないので内部のIDで並んでいてほしい。
- ついでに、現在開いているジャンルはちょっと違うコンポーネントになっててほしい。
やった
- 全体から考えて、まず色々をコンポーネントに変換してから、コンポーネントの内部で出し分けを行う
- コンポーネントを並べ替える
けっきょくこれは冗長になりすぎてダメだった。コンポーネントを並べるために情報を持たせないといけないし、並べ替えもしないといけない。
最終的にこうなった
- 全体のデータが入っている配列を
filterして「ジャンルなし」「ジャンル設定されてる」「ジャンル設定されてたけど参照していたジャンルが消えた」の3つに分けた- ポイント: 条件がMECEであるなら、
filterによる分割が成立する - そもそもこれは「並べ替え」というよりは「分類された上でconcatされている」と見るべきだった
- ポイント: 条件がMECEであるなら、
- 「ジャンル設定されてる」「ジャンル設定されてたけど参照していたジャンルが消えた」はその中で
sortする - 最終的に一直線に並んだので、
mapしてコンポーネントに変換した- 「現在開いている」まわりの処理はコンポーネント内部に閉じ込めればよい
気付き
最終的な案では、まず大本のデータを分割して、小さくしてから構成していき、最後にコンポーネントに収めるという形をとった。この形が成立するように構成するのがうまくいきやすいのかもしれない。 一般論として、分割統治したほうが考えることが少なくてよい。そして、分割したものの処理結果が出てきたら、あとはもう組み立てるだけで、その中身にほぼ触れる必要がない、というのが良い分割の指標だろうと思う。今回は分類してから分割統治すればいいだけの話だった。
また、雑に「ソート」と思っていたけれど、「並んでいてほしい」にも色々あり、単にそれは分類のことだった、ということもある。それはもうgroupByとかfilter+concatで考えるべきことで、「ソート」ではない。
運が良いとさらに大きい単位で数学的構造が見えてこれはモノイドですね〜みたいなモデル化が成功することもあるけど、ひとまずは実直に分割して統治したほうがいい。