はじめに
こちら でも類似の記事があり、参考にさせて頂きました。
以下、備忘録的な扱いとなりますが、誰かの役に立てば幸いです。
いくつかの方法
上記、参考サイトや他でも言及されていますが、filterとmapを両方使いたいケースで現状考えられる方法としては以下の4点かと思います。
- 素直にfilterした後mapする
- 逆にmapした後filterする
- reduceを使用する
- flatMapを利用する
個人的に一番スッキリ記述できるのがflatMapと思います。
サンプルコード
GAS、とりわけスプレッドシートを使うことが多いため、以下の前提で二次元配列から一次元配列を生成することとします。
- 「シート1」のA列に0~100までの数字が入力されている
- 値は1行目から入力されておりヘッダ行はなし
- 奇数のみの一次元配列を取得する
const sheetName = 'シート1';
const targetCol = 'A';
const SS = SpreadsheetApp.getActive();
const SH = SS.getSheetByName(sheetName);
const targetRange = SH.getRange(`$${targetCol}:$${targetCol}`);
const rawData = targetRange.getValues();
const resultArr = rawData.flatMap(row => row[0]%2 === 1? [row[0]]: []);
// resultArr => [1,3,5,...,99]
ポイント
三項演算子の返値 [row[0]]: []
が、個人的なポイントです。filterやmapを単独で使う場合が多いため、[]
で値を囲うことを忘れます。
今回はGAS及びスプレッドシート利用前提のため、二次元配列を扱っていますが、多次元(ジャグ配列)においても、一次元配列への変換時は返値を []
で囲う必要があります。
なお、偽値の場合に空配列 []
を返すことで、filterと同様の結果を得ることができます。その詳細についてはMDNにて以下のように説明されています。
flatMap は、map 中にアイテムの追加と削除(アイテムの数を変更)を行う方法として利用できます。つまり、常に一対一ではなく、(中略)アイテムを削除するには 0 要素の配列を返します。
引用元:Array.prototype.flatMap() - JavaScript | MDN
結果として、filterしつつmapも行う(逆も然り)、ということになるのですね。
最後に
サンプルでは単純な処理となっていますが、例えば、条件判定に至るまでの工程が長い場合でも、最終的に振り分けできれば問題ないと思います。filterとmapを分けて記述するより、わずかに効率的かと思いますが、好みやハウスルール、ケースによります。あとは、いかにそれまでの工程をリーダブルかつコンパクトにできるかがセンスなのでしょうね。
ただし、実行環境や処理内容によってはfilter後にmapする方が体感的にも早いと思います。
以上、誰かの役に立てば幸いです。