LoginSignup
0
0

More than 3 years have passed since last update.

JavascriptでRange関数を書いてみた

Last updated at Posted at 2020-12-03

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;

}

startstepは省略可能で、どの引数も負数を指定しても動くようになっている。
startendに対する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" );
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0