以前に書いた【JavaScript】文字列の配列で正規表現にマッチするものだけを取り出す方法という記事では、bind
メソッド (Function.prototype.bind
1)とビルトイン関数をうまく活用した例を紹介したつもりのですが、後日その例が良くないこと(bind
なしでかつ可読性も高い書き方があった)に気付きました。
その後もbind
メソッドをうまく活用した例を考えた続けていたところ、今度こそ(?)は良い例を見つけました。
今回はFunction.prototype.bind
1, Array.prototype.some
2, RegExp.prototype.test
3を組み合わせ、標題のことを実現する例を紹介します。
サンプル
まずはbind
なしで
Node.jsではprocess.argv
によって、コマンドライン引数が格納された配列(正確には3番目の要素から格納される4ので、process.argv.slice(2)
)を受け取ることができるので、これを用いた例を紹介します
const hasVersion = process.argv.slice(2).some(RegExp.prototype.test, /^(-v|--version)$/i);
console.log(hasVersion);
これは、コマンドライン引数に-v
または--version
が指定された場合にtrue
, 指定されなかった場合にfalse
を表示する例となっています。
正規表現にフラグi
(大文字小文字の区別なし)を指定しているので、例えばコマンドライン引数に-V
が指定された場合にもtrue
が表示されます。
実行結果は以下の通りです
$ node test01
false
$ node test01 -v
true
$ node test01 -V
true
$ node test01 --version
true
$ node test01 --readonly --VERSION
true
bind
登場
-v
または--version
の有無の判定の他に、-ro
または--readonly
の有無の判定もしたいといったケースも考えられると思います。
引数に正規表現を指定すると、コマンドライン引数にマッチするものがあるか判定する関数があると便利そうです。
以下の例では checkArgs
がそのような関数となっていて、bind
を用いて生成されています。
// const checkArgs = Array.prototype.some.bind(process.argv.slice(2), RegExp.prototype.test);
const checkArgs = [].some.bind(process.argv.slice(2), /./.test);
console.log('Version:', checkArgs(/^(-v|--version)$/i));
console.log('ReadOnly:', checkArgs(/^(-ro|--readonly)$/i));
[]
と/./
は、Array.prototype.some
とRegExp.prototype.test
を呼び出すためだけにあるリテラルとなっています(詳しくは以前に書いた記事を参照)
実行結果は以下の通りです
$ node test02
Version: false
ReadOnly: false
$ node test02 -v
Version: true
ReadOnly: false
$ node test02 -ro -v
Version: true
ReadOnly: true
$ node test02 --readonly --VERSION
Version: true
ReadOnly: true
$ node test02 --version --ReadOnly
Version: true
ReadOnly: true
$ node test02 --version -Ro
Version: true
ReadOnly: true
また、const
宣言を除けばECMAScript 6以上の仕様は使っていないので、Internet Explorer 11でも動作しました。
IE11のコンソール上での実行例
var checkArgs = [].some.bind(['Red', 'Green', 'Blue', 'White'], /./.test);
checkArgs(/^White$/i);
checkArgs(/^R/i);
checkArgs(/Black/i);
実行結果は以下の通りです
配列のindexOf
, includes
メソッドよりも良いところ
今回紹介した方法がindexOf
メソッド(Array.prototype.indexOf
5), includes
メソッド(Array.prototype.includes
6)と比べて良いところをまとめました
- 大文字小文字の区別をしない指定(フラグ
i
)やOR検索といった正規表現の機能を利用できる - ECMAScript 5までの仕様のみ利用している
-
includes
メソッド(特定の要素が配列に含まれているかどうかを真偽値で返す6)はES5までに入っていない
-