Array.mapを使ったループ処理の中である要素の処理を飛ばしたかったがcontinueは使えなかった。
調べるとreduceでやれってことだったが中々理解しにくかったので取り合えず自分用にメモしておく。
以下はmapでの(上手くいかなかった)実装と、それをreduceに置き換えたもの。
処理としては整数の入った配列による入力を受け取り、偶数のものだけを配列として返す。
filterを使えば簡単だった
filterを使った処理
const array = [1, 4, 9, 16];
const result = array.filter(x => x%2===0);
console.log(result);
> Array [4, 16]
filterを使った処理(冗長なの)
const array = [1, 4, 9, 16];
const map = array.map(x => {
if (x%2===0){
return x;
}
}).filter(x => x);
console.log(map);
> Array [4, 16]
以下、filterを知らない時のあがき
mapを使った処理
まずは偶数とか関係なしにmapからarrayの中身を順次returnで返却するもの。
const array = [1, 4, 9, 16];
const map = array.map(x => {
return x;
});
console.log(map);
> Array [1, 4, 9, 16]
偶数だけ返したいのでとりあえずifつけてreturnのみで返してみる。
const array = [1, 4, 9, 16];
const map = array.map(x => {
if (x % 2 === 0){
return x;
}
});
console.log(map);
> Array [undefined, 4, undefined, 16]
次にとりあえずcontinueで返そうとしてみる。
const array = [1, 4, 9, 16];
// pass a function to map
const map = array.map(x => {
if (x % 2 !== 0){
continue;
}
return x;
});
console.log(map);
Error: Illegal continue statement: no surrounding iteration statement
もちろん怒られる。
reduceを使った処理
reduceでは引数にコールバック関数と初期値を渡す。
mapから単純に置き換える場合は以下のような感じ。
mapをreduceで置き換え。
accumulatorなる現在の累積値を示す変数を追加。
初期値を空の配列に(return後の部分)。
if条件でcurrentValue(現在処理している値)が偶数の場合、accumulatorにpush。
accumulatorをreturnする。
const array = [1, 4, 9, 16];
const reduce = array.reduce((accumulator, currentValue) => {
if (currentValue%2 === 0) {
accumulator.push(currentValue);
}
return accumulator;
}, []);
console.log(reduce);
> Array [4, 16]
これを求めていた。
この辺りの説明はMDNが一番詳しく、同じような例も挙げられていた。
reduce自体に慣れておらず完全に理解しているとは言い難いが、上記で一応求めていた動作をする。
そんなアホなことしないでも別の方法があるのに…って時はぜひ教えてください。
参考
MDN web docs - Array.prototype.reduce()
MDN web docs - Array.prototype.map()
stack over flow - How to skip over an element in .map()?