20140115 ES6記法を追加(from jserさん)
RubyではRangeオブジェクトは便利なのでよく使います。
>> (1..10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Javascriptだと
Javascriptでも同じようなものが無いのか探してみると、いくつかありました。
1. forで回してArray.push
とりあえず普通に書いてみました。
function range(from, to) { var ar = []; for (var i=from; i <= to; i++) { ar.push(i) } return ar; } range(1,10) => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2. Underscore.js range を使う
もっとsmartな方法はないかと調べたら undersocre で実装されていました。undersocre 便利。
_.range(1, 11); => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
underscore/underscore.js at master · jashkenas/underscore · GitHub
中身を見ると、結局forで回してArrayに突っ込んでます。
_.range = function(start, stop, step) { if (arguments.length <= 1) { stop = start || 0; start = 0; } step = step || 1; var length = Math.max(Math.ceil((stop - start) / step), 0); var range = Array(length); for (var idx = 0; idx < length; idx++, start += step) { range[idx] = start; } return range; };
3. 黒魔術
速度は遅いようですが、こういうのもあるようです(あくまで参考)。
Does JavaScript have a range() equivalent? - Stack Overflow
Array.apply(null, Array(5)).map(function (_, i) {return i;}); => [0, 1, 2, 3, 4]
まだこれは理解できます。
JavaScriptで0からn-1までを要素にもつArrayを作成する方法 - blog.scheakur.com
こっちがすごいです。
Array.apply(null, {length: 5}).map(Number.call, Number) => [0, 1, 2, 3, 4]
最初の{length: 5} っていうのは思い浮かばないですし、mapの中が意味不明です。
(リンク先はすごい丁寧に解説されています。勉強になりました。)
apply、callを使いこなすといろいろできそうですね。
4. immutable-js
いまこれをモリモリ使っている人は少ないと思いますが
facebookのimmutable.js を使うと取得できます。
React + immutable.js が流行るんでしょうか。
Immutable.Range(1, 11).toArray(); => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
immutable-js/IterableImpl.js at master · facebook/immutable-js · GitHub
toArray() { assertNotInfinite(this.size); var array = new Array(this.size || 0); this.valueSeq().__iterate((v, i) => { array[i] = v; }); return array; },
5. ES6
id:jser さんに教えていただいたES6記法です。
[...Array(3).keys()] => Array [ 0, 1, 2 ]
iterableなobjectはドット3つで展開できるようです。実装はfirefox、safariのみのようですが、 Rubyの配列展開(*)のようで面白いです。
Spread operator - JavaScript | MDN
ほかにも調べてみると Array.from() というのも実装されたようです。
Array.from(Array(3).keys())
Array.from() - JavaScript | MDN
しかし、MDNはドキュメントが充実していますなぁ。