Posted at

JavaScriptにおける配列の空要素除去filterパターン

More than 1 year has passed since last update.

nullやundefinedなどのfalsyな要素を除去し新しい配列を取得するにはfilterを使うのは知られている。

filterはtrueとなる要素のみの新しい配列を生成する関数であるが、いくつかパターンがある。


filter(v => v)

const arr = [1, 2, 3, null, 5, undefined, false, 7]

const x = arr.filter(v => v)
console.log(x) // [ 1, 2, 3, 5, 7 ]

よく見る。


filter(v => !!v)

const arr = [1, 2, 3, null, 5, undefined, false, 7]

const y = arr.filter(v => !!v)
console.log(y) // [ 1, 2, 3, 5, 7 ]

!!でBooleanに変換する。

個人的にはあまり好きではない。


filter(Boolean)

const arr = [1, 2, 3, null, 5, undefined, false, 7]

const z = arr.filter(Boolean)
console.log(z) // [ 1, 2, 3, 5, 7 ]

このパターンを採用しているライブラリはBabelやrollupなど

https://github.com/babel/babel/blob/5cc1cbf3bc4ea8b93b48e9338c544d7cd6cefdb8/packages/babel-types/src/index.js#L415

https://github.com/rollup/rollup/search?utf8=%E2%9C%93&q=filter%28+Boolean+%29&type=


ベンチマーク

const { Suite } = require('benchmark')

const suite = new Suite()

const arr = [1, 2, 3, null, 5, undefined, false, 7]

suite
.add('filter(v => v)', function() {
arr.filter(v => v)
})
.add('filter(v => !!v)', function() {
arr.filter(v => !!v)
})
.add('filter(Boolean)', function() {
arr.filter(Boolean)
})
.on('cycle', function(event) {
console.log(String(event.target))
})
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'))
})
.run({ async: true })

// filter(v => v) x 1,128,274 ops/sec ±1.22% (87 runs sampled)
// filter(v => !!v) x 1,121,664 ops/sec ±0.75% (89 runs sampled)
// filter(Boolean) x 1,122,628 ops/sec ±1.26% (90 runs sampled)
// Fastest is filter(v => v),filter(Boolean)

優劣なし。


まとめ

好み。