JavaScriptに関するお知らせ

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

【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の違い

POPULAR

    LATESTS