LoginSignup
0
0

More than 1 year has passed since last update.

group_byでリファクタリング

Last updated at Posted at 2023-05-04

はじめに

  • JavaScriptでgroup_byを使って、手続き型のアルゴリズムをコレクション操作の関数型アルゴリズムにリファクタリング

座標点とポリラインの入力でまとめて処理

入力データは点の集まりだが、途中に名前がついてない点は直前の点に付随してポリラインを構成したい。
配列添字3番目のデータは、直前の2番目のデータと合わせて配列にする。その他の点は要素数1の配列で良い、とする。

スクリーンショット 2023-05-04 10.52.44.png

手続型

                this.sequences = list.inject([], (sequences, src, row_i) => {
                    if (row_i < (this.isIgnore ? this.ignoreLines : 0))
                        return sequences;

                    if (
                        this.thead.every((attr, i) =>
                            attr == 'ignore' ? true : src[i] == null
                        )
                    )
                        return sequences; // 空行はスキップ

                    const point = this.thead.inject({}, (p, attr, i) => {
                        if (attr == 'ignore') return p;
                        return p._assign(attr, src[i]);
                    }); //データ構造をオブジェクトに変える

                    if (sequences.last() == null) { //結果が何もなければ点として積む
                        sequences.push([point]);
                    } else if ( // 名前がないか、直前の点と同じなら、積んだ配列の最後に加える
                        point.name == '' ||
                        point.name == sequences.last()[0].name
                    ) {
                        sequences.last().push(point);
                    } else { //新たな点として積む
                        sequences.push([point]);
                    }
                    return sequences;
                });

group_byを使って関数型にする

                const sequences = list.filter((sequence, i) => {
                    return (
                        i >= (this.isIgnore ? this.ignoreLines : 0) &&
                        this.thead.some((attr, j) =>
                            attr == 'ignore' ? false : sequence[j] != null
                        )
                    );
                }); // まず必要なものだけ残す

                const sequencesList = sequences
                    .map((sequence) => {
                        return this.thead.inject({}, (p, attr, i) => {
                            if (attr == 'ignore') return p;
                            return p._assign(attr, sequence[i]);
                        });
                    })// オブジェクトに変換する
                    .group_by((point, i, self) => {
                        if (point.name = '') 
                            return point.name; //nameプロパティの値でグループ化
                                                 
                        const p = self.slice(0, i) // nameが''なら、元配列の自己位置から
                                .findLast(({ name }) => name != ''); //逆向きに探索
                        return p.name;   //結果の値でグループ化                      
                    });

なお、group_byとは

function group_by(cond){
    return Object.values(this.reduce(function (ret, e, i, self) {
                var val = cond(e, i, self); 
                if (ret[val] == null) //与えた評価関数の値をキーとする配列を作る
                   ret[val] = [e];
                else 
                   ret[val].push(e);    // キーが存在すれば配列に積む
                return ret;
            }, {})
    )     // キーは捨てて、配列を値とする配列を戻り値とする
}
0
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
0
0