JavaScriptに関するお知らせ

SINCE2019
>
【JS】reduceの使い方と破壊力-3.everyもsomeもfindも、もう全部reduceでいいの。

【JS】reduceの使い方と破壊力-3.everyもsomeもfindも、もう全部reduceでいいの。


こんにちは!reduce過激派です。

前回に引き続き、今回もreduceを使って色んなメソッドを代替していきます:)

every

everyは配列の全てが条件を満たすとtrue、じゃないとfalseが返るメソッドです。

他言語だとallだったり、論理回路や集合論だとandだったりしますねーー

早速全て5以下ならtrueのコードを書いてみるわ

const arr = [0, 1, 2, 0, 8, 2, 8, 8, 2, 8]
const answer = arr.every(n => n < 5)

console.log(answer) // false

reduceでevery

reduceでやるとこう

const arr = [0, 1, 2, 0, 8, 2, 8, 8, 2, 8]
const answer = arr.reduce((pre, cur) => pre && cur < 5, true)

console.log(answer) // false

長い。その上無駄に複雑!

some

someはeveryよりも緩く、配列のどれか一つでも条件に合えばtrueです。

他言語のany、集合だとorですね!

一つでも5以下ならtrueのをやってみます

const arr = [0, 1, 2, 0, 8, 2, 8, 8, 2, 8]
const answer = arr.some(n => n < 5)

console.log(answer) // true

reduceでsome

reduceでやると

const arr = [0, 1, 2, 0, 8, 2, 8, 8, 2, 8]
const answer = arr.reduce((pre, cur) => pre || cur < 5, false)

console.log(answer) // true

長いのは勿論なんですが、これパッと見てeveryと見分けつかないですよね? そっちの方が問題だよね。

find

findは配列の要素のうち最初に条件を満たす要素をreturnします。

一番最初の5以上の数字を取得してみよう

const arr = [0, 1, 2, 0, 8, 2, 8, 8, 2, 8]
const answer = arr.find(n => n > 5)

console.log(answer) // 8

reduceでfind

はい

const arr = [0, 1, 2, 0, 8, 2, 8, 8, 2, 8]
const answer = arr.reduce(
  (pre, cur) => (pre === null ? (cur > 5 ? cur : null) : pre),
  null,
)

console.log(answer) // 8

悪の化身、多重三項演算子が登場しました。

もう一つ、悲しいお知らせがあります。

mapとfilterはともかく、every,some,findはreduceで代替すると遅い。遅いです。

特に配列が長くなってくるとべらぼうに遅い。

reduceはどこへ向かうのか

やはりよほどのreduceオタクでもない限り、単体で使うのは厳しいでしょう。可読性がやばい。

前回の記事でも書いた通り、このうちのいくつかのメソッドを組み合わせて使う際に 威力を発揮しそうですね:)

例えばsomeとeveryを同時に判定するとか↓

const arr = [0, 1, 2, 0, 8, 2, 8, 8, 2, 8]
const answer = arr.reduce(
  (pre, cur) => ({
    some: pre.some || cur < 5,
    every: pre.every && cur < 5,
  }),
  {
    some: false,
    every: true,
  },
)
console.log(answer) // some: true, every: false

3番目に条件に一致する数を返すとか↓

const arr = [0, 1, 2, 0, 8, 2, 8, 8, 2, 8]
const answer = arr.reduce(
  (pre, cur) =>
    pre.i == null
      ? pre
      : pre.i - 1 === 3 && cur < 5
        ? cur
        : cur < 5
          ? { i: pre.i + 1, n: null }
          : { ...pre },
  {
    i: 0,
    n: null,
  },
)
console.log(answer) // 2 (3番目の5以下の数)

こんな感じ!すごい!reduceはこういう時すごい!

余談

論理回路でNANDのみを使って全てを表すやつあるんですよ。こういうやつ

NAND回路のみでANDやOR,XORや多数決回路を作る

「reduceのみでmapやfilter、someやeveryを作る」

...似てる!素敵。

余談2

平成最後の記事でした。さらば平成



PREV
2019-04-27
【JS】アロー関数で短く省略できる6つの表記

NEXT
2019-05-01
【JS】令和でわかるnullとundefinedの違い