Javascriptの組み込み関数には連番入った配列を返すような「Range関数」がない。
もしあれば、for-of
文などと組み合わせて簡潔に書ける処理が増えるだろう。
使用イメージ
for ( const value of Range( 10, 20 ) ) {
//value = 10, 11, 12, ... 19
}
#実際に書いてみる
パフォーマンスなどは無視して、単純に書くと配列を返す処理になるだろう。
しかし、何万何十万という巨大な連番を振る場合には不都合が大きい。
要は iteratable を返せば良いのでジェネレーター関数とすれば良いだろう。
Range( [start,] end [, step] )
function* Range( ...args ) {
let start, end, step;
switch ( args.length ) {
case 0: throw new TypeError( "argument expected" );
case 1: [ end ] = args; break;
case 2: [ start, end ] = args; break;
default:[ start, end, step ] = args; break;
}
[ start, end ] = [ start, end ].map( val => val == null ? 0 : Number( val ) );
if ( step == null ) step = start < end ? 1 : -1;
else step = Number( step );
if ( [ start, end, step ].some( e => isNaN( e ) ) ) throw new TypeError( "illegal argument" );
if ( step == 0 ) throw new TypeError( "illegal argument" );
else if ( step < 0 )
if ( start < end ) throw new TypeError( "illegal argument" );
else for ( let value = start; value >= end; value += step ) yield value;
else
if ( start > end ) throw new TypeError( "illegal argument" );
else for ( let value = start; value <= end; value += step ) yield value;
}
start
とstep
は省略可能で、どの引数も負数を指定しても動くようになっている。
start
とend
に対するstep
の正負が不正か、いずれかの引数がNaN
の場合はNGになる。
使用例
const maru = String.fromCharCode( ...Range( 13008, 13054 ) );
console.time( "TEST 1" );
for ( const times of Range( 100000 ) ) {
//TEST
}
console.timeEnd( "TEST 1" );