map や filter の際に console.log() しながら短くアロー関数を書く

ES2015 で登場したアロー関数。慣れないうちは読みづらいかもしれないが、省略記法がいくつかあり、return を省略できたりするので、map()filter() などで簡潔に書ける場合は利用したい。

しかし、処理中に console.log() したかったりする場合もあり、そうすると途端にブレースを書いて、return を書いて…と、簡潔さを失ってしまう。

// 何らかの配列
const array = ['hoge', 'fuga', 'piyo', 'foo', 'bar'];

// せっかく簡潔に1行で map が済んでいたのに…
const shorthand = array.map(item => `[${item}]`);

// console.log を入れたいがために省略記法を止めることに…
const tooLong = array.map((item) => {
  console.log(`map:${item}`);
  return `[${item}]`;
});

しかし、console.log()void な関数、つまり戻り値が undefined であることと、論理演算子 || を使えば、1行で済ませることができる。

// console.log しながら map 処理!
const shorthand = array.map(item => console.log(`map:${item}`) || `[${item}]`);

少々トリッキーだが、undefined は Falsy な値なので、console.log() の後ろの処理が実行されるという仕組み。

const array = ['hoge', 'fuga', 'piyo', 'foo', 'bar'];

// map の場合
const result1 = array.map(item => console.log(`map:${item}`) || `[${item}]`);
console.log(result1);

// filter の場合も最終的に boolean を返せれば良いのでこう書ける
const result2 = array.filter(item => console.log(`filter:${item}`) || item.length < 4);
console.log(result2);

// forEach でも可能
let result3 = [];
array.forEach(item => console.log(`forEach:${item}`) || result3.push({ str: item }));
console.log(result3);

// 以下は「Invalid left-hand side in assignment」エラーになるので注意
// let result4 = '';
// array.forEach(item => console.log(`forEach:${item}`) || result4 += ` ${item} ` );

// こうすれば一応解決だが、こんな forEach なら素直に関数化したらいいかも…
let result4 = '';
array.forEach(item => result4 += console.log(`forEach:${item}`) || ` ${item} `);
console.log(result4);

ウーン、JS っぽくてカコイイ。ES2015 と互換性のある TypeScript などでも使えるのでぜひ。