1…Nを含む配列を作成する方法


1163

1からNまでを含むJavaScript配列を作成するための以下の代替手段を探しています。Nは実行時にのみ認識されます。

var foo = [];

for (var i = 1; i <= N; i++) {
   foo.push(i);
}

私には、ループなしでこれを行う方法があるはずだと感じています。


224
このページ全体を読んだ後、私はあなた自身の単純なforループが最も単純で、最も読みやすく、最もエラーが発生しにくいという結論に達しました。
ココドコ2014年

誰かがより高度なものを必要とする場合、数字、文字、負/正の範囲などに対してこれを行うnode.js ライブラリを作成しました。github.com / jonschlinkert / fill-rangegithub.com/jonschlinkert/bracesでブレース展開に使用され、github.com / jonschlinkert / micromatchでグロブパターンが使用されます
jonschlinkert

1
「... 1 ... Nを含む」の代わりに「長さNの配列を作成する方法」と言うように編集する必要があります。後者は、1からNの値を持つ要素があることを意味します
Steven Landow

7
@StevenLandow OPの名前を変更する必要があるのはなぜですか?彼は値を持つ配列が必要です1 ... Nか?
Andre Elrico

良い質問、良いタイトル、(ちょっと)ばかげた答え。
Bitterblue

回答:


381

私があなたが何を求めて1..nいるかがわかった場合、後でループできる数値の配列が必要です。

これで十分な場合は、代わりにこれを実行できますか?

var foo = new Array(45); // create an empty array with length 45

次に、それを使用したい場合...(たとえば、最適化されていない)

for(var i = 0; i < foo.length; i++){
  document.write('Item: ' + (i + 1) + ' of ' + foo.length + '<br/>'); 
}

たとえば、配列に何も格納する必要がない場合は、反復できる適切な長さのコンテナーが必要なだけです...これは簡単かもしれません。

ここで実際にそれを見てください:http : //jsfiddle.net/3kcvm/


4
あなたが私の質問を私よりもうまく表現できたことに感銘を受けました。反射に関して必要なのは、後でループできる数値の配列だけなので、本当に正しいです:)回答ありがとうございます。
Godders

147
@Godders:これがあなたが探しているものなら、なぜ配列が必要なのですか?単純でvar n = 45;、次にループする1..nことで十分です。
カサブランカ2010

3
@Godders-作成した配列のサイズを長さMに減らしたい場合は、単純にfoo.length = M---カットオフ情報が失われることに注意してください。実際の動作を見る==> jsfiddle.net/ACMXp
Peter Ajtai

24
なぜこの回答に賛成投票があるのか​​、本当にわかりません。特にOP自身が同意した場合、上記のいくつかのコメントでは意味がありませんvar n = 45;
plalx 2013年

72
@scunliffe:new Array(45);「45要素の配列を作成する」ことはできません(同じ意味で[undefined,undefined,..undefined])。むしろ、「長さ= 45の空の配列を作成する」([undefined x 45])と同じvar foo = []; foo.length=45;です。そのためforEachmapこの場合は適用されません。
tomalec 2014年

1310

ES6では、Array from()およびkeys()メソッドを使用します。

Array.from(Array(10).keys())
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

スプレッド演算子を使用した短いバージョン。

[...Array(10).keys()]
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

75
注:これは常に0 から始まりmapます。値([...Array(10).keys()].map(x => x++);)を調整して1から始めるには、配列にaをチェーンする必要があります
Sterling Archer

32
値が返された後、優先度が上がるためにに変更map(x => x++)するだけmap(x => ++x)です:)
Brock

93
えっ!なぜmap簡単にできるのですsliceか? [...Array(N+1).keys()].slice(1)
ロビン

19
または、使用keysせずに1つのマップのみ->Array.from(Array(10)).map((e,i)=>i+1)
yonatanmn '29

60
または、キーとマップを使用せず、マッピング関数を渡すだけfrom Array.from(Array(10), (e,i)=>i+1)
Fabio Antunes

844

あなたはそうすることができます:

var N = 10; 
Array.apply(null, {length: N}).map(Number.call, Number)

結果:[0、1、2、3、4、5、6、7、8、9]

またはランダムな値で:

Array.apply(null, {length: N}).map(Function.call, Math.random)

結果:[0.7082694901619107、0.9572225909214467、0.8586748542729765、0.8653848143294454、0.008339877473190427、0.9911756622605026、0.8133423360995948、0.8377588465809822、0.5577575915958732、0.16363654541783035]

説明

まず、これNumber.call(undefined, N)はと同じでNumber(N)、を返すだけNです。その事実は後で使用します。

Array.apply(null, [undefined, undefined, undefined])Array(undefined, undefined, undefined)3要素の配列を生成し、undefined各要素に割り当てると同等です。

それをどのようにN要素に一般化できますか?どのようにArray()機能するかを考えてみましょう。これは次のようになります。

function Array() {
    if ( arguments.length == 1 &&
         'number' === typeof arguments[0] &&
         arguments[0] >= 0 && arguments &&
         arguments[0] < 1 << 32 ) {
        return [  ];  // array of length arguments[0], generated by native code
    }
    var a = [];
    for (var i = 0; i < arguments.length; i++) {
        a.push(arguments[i]);
    }
    return a;
}

ECMAScriptの5のでFunction.prototype.apply(thisArg, argsArray)また、その2番目のパラメータとしてアヒル型付けされた配列のようなオブジェクトを受け付けます。を呼び出すとArray.apply(null, { length: N })、実行されます

function Array() {
    var a = [];
    for (var i = 0; i < /* arguments.length = */ N; i++) {
        a.push(/* arguments[i] = */ undefined);
    }
    return a;
}

これで、各要素がに設定されたN要素の配列ができましたundefined。これを呼び出す.map(callback, thisArg)と、各要素はの結果に設定されcallback.call(thisArg, element, index, array)ます。したがって、[undefined, undefined, …, undefined].map(Number.call, Number)各要素を(Number.call).call(Number, undefined, index, array)にマップします。これはと同じです。これは、Number.call(undefined, index, array)以前に観察したように、に評価されindexます。これで、要素がインデックスと同じである配列が完成しました。

なぜArray.apply(null, {length: N})ただの代わりにのトラブルを経験するのArray(N)ですか?結局のところ、両方の式は、未定義の要素のN要素の配列になります。違いは、前者の式では各要素が明示的に未定義に設定されているのに対し、後者では各要素が設定されたことはないということです。のドキュメントによると.map()

callback値が割り当てられている配列のインデックスに対してのみ呼び出されます。削除されたインデックス、または値が割り当てられていないインデックスに対しては呼び出されません。

したがって、Array(N)不十分です。Array(N).map(Number.call, Number)結果は、長さがNの初期化されていない配列になります。

互換性

この手法はFunction.prototype.apply()ECMAScript 5 で指定された動作に依存しているため、Chrome 14やInternet Explorer 9などのECMAScript 5より前のブラウザーでは機能ません


62
賢い場合は+1ですが、これはプリミティブなforループよりも桁違いに遅いことに注意してください:jsperf.com/array-magic-vs-for
warpech

7
非常に賢い-おそらくあまりにも。Function.prototype.callの最初のパラメーターがのイテレーターパラメーターにthis直接マップするオブジェクトであるという事実を利用するとArray.prototype.map、ある程度の輝きがあります。
Noah Freitas

14
これは本当に、本当に賢いです(JSの乱用に関する境界線)。ここで本当に重要な洞察は、map私の意見では、割り当てられていない値の特異性です。別のバージョンが(そしておそらく少し明確に、長くはあるが)である: Array.apply(null, { length: N }).map(function(element, index) { return index; })
ベン・ライヒ

6
@BenReich(JS乱用レベルの観点から)さらに良い:Array.apply(null, new Array(N)).map(function(_,i) { return i; }) または、es6および矢印関数の場合はさらに短い:Array.apply(null, new Array(N)).map((_,i) => i)
奇妙な

1
これが1から始まる配列を返す場合、実際にはOPの質問に答えます
Sarsaparilla

483

ES6を使用する複数の方法

スプレッド演算子(...)とキーメソッドの使用

[ ...Array(N).keys() ].map( i => i+1);

塗りつぶし/マップ

Array(N).fill().map((_, i) => i+1);

Array.from

Array.from(Array(N), (_, i) => i+1)

Array.fromと{ length: N }hack

Array.from({ length: N }, (_, i) => i+1)

一般化された形式に関する注意

変化させることにより、かなり上の任意の所望の値に初期化缶生産アレイ上のすべての形態i+1(例えば、必要な式にi*2-i1+i*2i%2およびなど)。式が何らかの関数で表現できる場合f、最初の形式は単純になります

[ ...Array(N).keys() ].map(f)

例:

Array.from({length: 5}, (v, k) => k+1); 
// [1,2,3,4,5]

配列はundefined各位置で初期化v されるため、の値はundefined

すべてのフォームを紹介する例

カスタム初期化関数のより一般的な例、fすなわち

[ ...Array(N).keys() ].map((i) => f(i))

またはさらに簡単に

[ ...Array(N).keys() ].map(f)



5
0から始まる配列のための使用のk ++
Borgboy

1
インクリメントする場合はk++、を使用せず、を使用してください++k
Alex

4
Array.fromはIEでサポートされていません。
ローレン

2
TSコンパイラーを幸せにするために、未使用のパラメーターをlodashで置き換えることを検討してください:Array.from({length:5}、(_、k)=> k + 1);
Journeycorner

297

配列は元々長さを管理します。それらがトラバースされると、それらのインデックスはメモリに保持され、その時点で参照されます。ランダムなインデックスを知る必要がある場合は、このindexOf方法を使用できます。


これは、あなたのニーズのために、あなたは特定のサイズの配列を宣言したいかもしれないと言いました:

var foo = new Array(N);   // where N is a positive integer

/* this will create an array of size, N, primarily for memory allocation, 
   but does not create any defined values

   foo.length                                // size of Array
   foo[ Math.floor(foo.length/2) ] = 'value' // places value in the middle of the array
*/


ES6

拡大

スプレッド演算子(...)とkeysメソッドを使用すると、サイズNの一時配列を作成してインデックスを作成し、次に変数に割り当てることができる新しい配列を作成できます。

var foo = [ ...Array(N).keys() ];

塗りつぶし/マップ

最初に必要な配列のサイズを作成し、それを未定義で埋め、次にを使用して新しい配列を作成mapします。これにより、各要素がインデックスに設定されます。

var foo = Array(N).fill().map((v,i)=>i);

Array.from

これは、サイズNの長さに初期化し、1回のパスで配列を生成する必要があります。

Array.from({ length: N }, (v, i) => i)



コメントと混乱の代わりに、上記の例で1..Nから値を取得したい場合は、いくつかのオプションがあります。

  1. インデックスが使用可能な場合は、単純に1だけ増やします(例:)++i
  2. インデックスが使用されない場合、そしておそらくより効率的な方法は、配列を作成することですが、NをN + 1にしてから、前に移動します。

    したがって、100個の数値が必要な場合:

    let arr; (arr=[ ...Array(101).keys() ]).shift()





これは、受信側で処理できないデータに数値の配列が使用されている場合に役立つと思います。(値を置換するだけのHTMLテンプレートのように。)
Neil Monroe

誰かがこれを行う理由は、ユーザーに1〜10の選択肢を提供するために、ドロップダウンリストに入力する数値の配列を用意することです。手作業による小さな配列[1,2,3 ... 10]は理にかなっていますが、 1から50ですか?終了番号が変わった場合はどうなりますか?
CigarDoug 2018年

@CigarDougユースケースがあることは間違いありませんが、それは小さいと思います。なぜ数値の配列が必要になるのでしょうか。通常、配列を反復処理するとき、インデックスはループ構造の一部として使用されます。つまり、ループ本体関数への引数またはカウンター変数として使用されるため、数値の配列を保持することは簡単なようです。指定された幅の配列を作成するか、配列の上限を保持する変数を作成します。私はいくつかのユースケースを考えることができますが、それらのどれもOPによって表現されていませんでした
vol7ron、

4
先ほど言ったように、ドロップダウンに1〜10の数字を入力する必要があります。ユースケース、MYユースケースがあります。それが私がこのページを見つけた方法です。したがって、アレイを手動で作成するだけで、ここで見たものよりも複雑さが軽減されました。したがって、私の要件はOPの要件ではありません。しかし、私には答えがあります。
CigarDoug 2018年

1
@ vol7ronユースケースがあり、私も持っています。角張ったページングで、クリック可能なページをフッターに表示したいと思います。したがって、* ngFor = "let p of pagesCounter"を使用してビューの要素をループします。そのためのより良い解決策がありますか?ところで、stackoverflow.com
questions /

186

ES6でできること:

Array(N).fill().map((e,i)=>i+1);

http://jsbin.com/molabiluwa/edit?js,console

編集:質問を更新Array(45)したArray(N)ため、に変更されました。

console.log(
  Array(45).fill(0).map((e,i)=>i+1)
);


3
1、それは全体のだから、大きなOより良い厄介なより.join.splitバージョン-しかし、私はまだ謙虚なループが優れていると思います。
ロビン

@Robinに同意します-アルゴリズムの複雑さはさておき、控えめなループは常により読みやすくなります。しかし、Javaでのラムダの出現により、私mapはすぐにこのようなものの標準になると思います。
ネイト

4
const gen = N => [...(function*(){let i=0;while(i<N)yield i++})()]
ロビン

8
なぜ.fill()必要なのかわかりません。私はノードのreplでテストするときだとわかりますが、それ以降Array(1)[0] === undefinedArray(1).fill(undefined)makeでfill()を呼び出すとどのような違いがありますか?
2016年

11
興味のある他の人のために、Array(N)とArray(N).fill()の違いはここで
Dominic

108

非常に人気のあるアンダースコア_.rangeメソッドを使用する

// _.range([start], stop, [step])

_.range(10); // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11); // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5); // => [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1); //  => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
_.range(0); // => []


驚くばかり。とにかくアンダースコアを使用しない大きなプロジェクトを見せて...
Erez Cohen

63
function range(start, end) {
    var foo = [];
    for (var i = start; i <= end; i++) {
        foo.push(i);
    }
    return foo;
}

その後、

var foo = range(1, 5);

JavaScriptでこれを行う組み込みの方法はありませんが、複数回行う必要がある場合に作成するのに完全に有効なユーティリティ関数です。

編集:私の意見では、以下はより良い範囲関数です。たぶん私はLINQに偏っているからかもしれませんが、それはより多くのケースでより便利だと思います。あなたのマイレージは異なる場合があります。

function range(start, count) {
    if(arguments.length == 1) {
        count = start;
        start = 0;
    }

    var foo = [];
    for (var i = 0; i < count; i++) {
        foo.push(start + i);
    }
    return foo;
}

2
私はこれが好き。それをさらに使いたい場合は、Array.prototype.range = function(start、end){...};として宣言できます。次に、任意のArrayオブジェクトでrange(x、y)を呼び出すことができます。
Zach Rattner、2010

8
むしろ、すべての配列でこのメソッドを使用する理由がないので(かなり馬鹿げていると考えられることもあります)、Array代わりにのArray.prototypeメソッドにします。
アダムス

9
Array.range(1, 5)おそらくもっと適切でしょうが、を書くことについて何かクールなものがあり[].range(1, 5)ます。
MooGoo 2010

「むしろ、Array.prototypeではなくArrayのメソッドにする」-違いは何ですか?特定のアレイのみを意味しますか?
pilau

3
@pilauアダムスが言うように、それは奇妙に見えます。プロトタイプ上にある場合は、と言うことができますfoo = [1, 2, 3]; bar = foo.range(0, 10);。しかし、それはただ...混乱を招くだけです。bar = Array.range(0, 10)より明確で明示的です。範囲はインスタンスとは関係がないため、インスタンスメソッドにする理由はありません。
Ian Henry

53

Arrayv8に入力する最も速い方法は次のとおりです。

[...Array(5)].map((_,i) => i);

結果は次のようになります: [0, 1, 2, 3, 4]


余分な変数なしでそれを行う方法はありますか_
bluejayke

ノー@bluejayke :(
аlexdykyі

厳しい、あなたは.mapのソースコードが何であるか知っていますか?forループよりも高速かどうかはわかりませんが、そうでない場合は、理論的にはプロパティを定義して新しいプロパティを作成するだけです
bluejayke

49

この質問には多くの複雑な答えがありますが、簡単な1行です:

[...Array(255).keys()].map(x => x + 1)

また、上記の記述は短い(そしてきちんとした)ものですが、次の方が少し高速だと思います(最大長:

127、Int8、

255、Uint8、

32,767、Int16、

65,535、Uint16、

2,147,483,647、Int32、

4,294,967,295、Uint32。

最大整数値に基づく)、これも型付き配列の詳細です):

(new Uint8Array(255)).map(($,i) => i + 1);

このソリューションも2つの配列を作成し、追加の変数宣言 "$"を使用するため、あまり理想的ではありません(このメソッドを使用してそれを回避する方法は不明です)。私は次の解決策がこれを行うための絶対最速の方法だと思います:

for(var i = 0, arr = new Uint8Array(255); i < arr.length; i++) arr[i] = i + 1;

このステートメントが作成された後はいつでも、現在のスコープで変数「arr」を簡単に使用できます。

それから簡単な関数を作りたい場合(いくつかの基本的な検証を伴う):

function range(min, max) {
    min = min && min.constructor == Number ? min : 0;
    !(max && max.constructor == Number && max > min) && // boolean statements can also be used with void return types, like a one-line if statement.
        ((max = min) & (min = 0));  //if there is a "max" argument specified, then first check if its a number and if its graeter than min: if so, stay the same; if not, then consider it as if there is no "max" in the first place, and "max" becomes "min" (and min becomes 0 by default)

    for(var i = 0, arr = new (
        max < 128 ? Int8Array : 
        max < 256 ? Uint8Array :
        max < 32768 ? Int16Array : 
        max < 65536 ? Uint16Array :
        max < 2147483648 ? Int32Array :
        max < 4294967296 ? Uint32Array : 
        Array
    )(max - min); i < arr.length; i++) arr[i] = i + min;
    return arr;
}



//and you can loop through it easily using array methods if you want
range(1,11).forEach(x => console.log(x));

//or if you're used to pythons `for...in` you can do a similar thing with `for...of` if you want the individual values:
for(i of range(2020,2025)) console.log(i);

//or if you really want to use `for..in`, you can, but then you will only be accessing the keys:

for(k in range(25,30)) console.log(k);

console.log(
    range(1,128).constructor.name,
    range(200).constructor.name,
    range(400,900).constructor.name,
    range(33333).constructor.name,
    range(823, 100000).constructor.name,
    range(10,4) // when the "min" argument is greater than the "max", then it just considers it as if there is no "max", and the new max becomes "min", and "min" becomes 0, as if "max" was never even written
);


したがって、上記の関数を使用すると、上記の超低速の「単純なワンライナー」が超高速でさらに短くなります。

range(1,14000);

@JVGですが、より高速な関数ではありませんか?
bluejayke

その通りです。誰もが求めるこのシンプルなワンライナーです!
supersan

@supersanは超低速ですが:)
bluejayke

新しいfillメソッドを使用した最新のjavascript :Array(255).fill(0,0,255)
cacoder

@cacoderの速度、作成される配列の数、および反復の回数は?
bluejayke

42

あなたはこれを使うことができます:

new Array(/*any number which you want*/)
    .join().split(',')
    .map(function(item, index){ return ++index;})

例えば

new Array(10)
    .join().split(',')
    .map(function(item, index){ return ++index;})

次の配列を作成します:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

また、なぜnew Array(10).join().split(',').map(function() {return ++arguments[1]});ですか?
スーパー

1
@Murplyxの場合、内部に引数を持つ関数はJSエンジンによって最適化されません(V8の場合でもtrue、jsperf.com / arguments
vs

4
これは興味深い解決策ですが、完全に実用的ではありません-配列を3回(1回join、1回、1回split、実際にやりたいことのために)解析する必要があるのは、あまり良くありません-好意から外れているようです。何らかの理由で、しかし古き良き時代のループを単に使用する方がはるかに良いでしょう!
ロビン

42

ES6これはトリックを行います:

[...Array(12).keys()]

結果を確認してください:

[...Array(12).keys()].map(number => console.log(number))


5
実際、彼らは0..N-1ではなく1..Nを求めました
YakovL 2018年

1
はい、[...Array(N + 1).keys()].slice(1)1..Nを生成します
David G

何らかの理由で、このソリューションはExpo(react-native)アプリの製品版では機能しません。[...Array(N + 1).keys()]このコードは空の配列を返しますが、プロダクションモードでは、開発モードを使用しても機能します。
FabianoLothor

3
.keys()答えはすでに与えられた数年前と500 + upvotesを持っています。あなたの答えはそれに何を追加しますか?
Dan Dascalescu 2018

39

たまたまd3.jsを使用している場合私のようにアプリでを、D3はこれを行うヘルパー関数を提供します。

したがって、0から4までの配列を取得するには、次のように簡単です。

d3.range(5)
[0, 1, 2, 3, 4]

そして、あなたが要求していたように1から5までの配列を取得するには:

d3.range(1, 5+1)
[1, 2, 3, 4, 5]

詳細については、このチュートリアルをご覧ください。


このコメントにより、RamdaJSでrange()関数を検索するというアイデアが得られまし。これは、たまたま現在のプロジェクトで作業しているJSライブラリです。完璧です。
モーフィック2015


38

これはおそらく、数値の配列を生成する最も速い方法です

最短

var a=[],b=N;while(b--)a[b]=b+1;

列をなして

var arr=(function(a,b){while(a--)b[a]=a;return b})(10,[]);
//arr=[0,1,2,3,4,5,6,7,8,9]

1から始めたい場合

var arr=(function(a,b){while(a--)b[a]=a+1;return b})(10,[]);
//arr=[1,2,3,4,5,6,7,8,9,10]

機能が必要ですか?

function range(a,b,c){c=[];while(a--)c[a]=a+b;return c}; //length,start,placeholder
var arr=range(10,5);
//arr=[5,6,7,8,9,10,11,12,13,14]

どうして?

  1. while 最速のループです

  2. 直接設定は push

  3. [] より速い new Array(10)

  4. それは短いです...最初のコードを見てください。次に、ここにある他のすべての関数を確認します。

あなたが好きならなしでは生きられないため

for(var a=[],b=7;b>0;a[--b]=b+1); //a=[1,2,3,4,5,6,7]

または

for(var a=[],b=7;b--;a[b]=b+1); //a=[1,2,3,4,5,6,7]

8
これらの主張をベンチマークでバックアップすることをお勧めします。jsperf.comをお試しください。
マットボール

2
あなたが私の答えストップ私の他の人をdownvoting ...好きではないだけbeacuseマットplsは... jsperf笑 stackoverflow.com/a/18344296/2450730 ...使用console.time()またはどのようにそれを呼び出してない... jsperf 。
cocco 2013

4
参考までに:John Reisigが数年前に最初に公開されたとき-一部のプラットフォーム(Windows:Pを意味します)では、16ミリ秒に1回ブラウザーに時間が供給されています。また、マルチタスク環境での実行時間の測定には他の問題もあります。jsperf.comは、統計的に正しいようにテストの実行を実装しました。これは、実行するために大丈夫だconsole.time()直感を取得することではなく、証明のために、あなたはjsperf.com必要性と、それはあなたが他の人からの結果(異なるハードウェアなど)、ブラウザの交差を示す
naugtur

3
@coccoこれは正しくありません:var a=[],b=N;while(b--){a[b]=a+1};
vintagexav

5
@ cocco- しばらくはないが、常に他のループよりも速く。一部のブラウザでは、whileループのデクリメントがforループよりもはるかに遅いため、JavaScriptのパフォーマンスに関する一般的なステートメントを作成することはできません。これは、非常に多くの異なる最適化を伴う実装が多数存在するためです。しかし、一般的に私はあなたのアプローチが好きです。;-)
RobG 2015

32

あなたがlodashを使用している場合は、使用することができ_.rangeを

_.range([start=0], end, [step=1])

開始から終了までの数値(正および/または負)の配列を作成します。負の開始が終了またはステップなしで指定されている場合、-1のステップが使用されます。endが指定されていない場合は、startで始まり、0に設定されます。

例:

_.range(4);
// ➜ [0, 1, 2, 3]

_.range(-4);
// ➜ [0, -1, -2, -3]

_.range(1, 5);
// ➜ [1, 2, 3, 4]

_.range(0, 20, 5);
// ➜ [0, 5, 10, 15]

_.range(0, -4, -1);
// ➜ [0, -1, -2, -3]

_.range(1, 4, 0);
// ➜ [1, 1, 1]

_.range(0);
// ➜ []

32

充填の新しい方法Arrayは次のとおりです。

const array = [...Array(5).keys()]
console.log(array)

結果は次のようになります: [0, 1, 2, 3, 4]


技術的には0-(N-1)ではなく1-Nからの質問でしたが、これは本当に良い答えです
bluejayke

30

ES6でできること:

// `n` is the size you want to initialize your array
// `null` is what the array will be filled with (can be any other value)
Array(n).fill(null)

配列の値は、実際にこのソリューションを用いて充填され、以来mapforEach動作します。
dontmentionthebackup

27

最終要約レポート.. Drrruummm Rolll-

これは、ES6を使用せずにサイズN(ここでは10)の配列を生成するための最短のコードです。上記のCoccoのバージョンは近いですが、最短ではありません。

(function(n){for(a=[];n--;a[n]=n+1);return a})(10)

しかし、このコードゴルフ(ソースコードの最小バイトで特定の問題を解決するための競争)の誰もが認める勝者は、Niko Ruotsalainenです。配列コンストラクターとES6スプレッド演算子を使用します。(ES6構文のほとんどは有効なtypeScriptですが、以下はそうではありません。そのため、使用する際は慎重に行ってください)

[...Array(10).keys()]

なぜ反対票?長い回答リストを理解するのは難しいので、要約すると考えました。
2016

これは0-10じゃないですか?[... Array(10).keys()]
Greg

Webstormは(新しいArray(10))。keys()を提案しています、それは正しいですか?
Guy

(新しいArray(10))。keys()は、配列ではなくArrayIterator {}を返します
sapy

これにより、グローバル変数が作成されますa。ループはfor(var a=[];n--;a[n]=n+1)
2016

20

ES6には、2つの引数を取るArray.fromを使用する別の方法があります。1つ目はarrayLike(この場合はlengthプロパティを持つオブジェクト)、2つ目はマッピング関数(この場合はアイテムをそのインデックスにマッピングします)です。

Array.from({length:10}, (v,i) => i)

これは短く、偶数を生成するような他のシーケンスに使用できます

Array.from({length:10}, (v,i) => i*2)

また、これは配列を1回だけループするため、他のほとんどの方法よりもパフォーマンスが優れています。比較のために抜粋を確認してください

// open the dev console to see results

count = 100000

console.time("from object")
for (let i = 0; i<count; i++) {
  range = Array.from({length:10}, (v,i) => i )
}
console.timeEnd("from object")

console.time("from keys")
for (let i =0; i<count; i++) {
  range = Array.from(Array(10).keys())
}
console.timeEnd("from keys")

console.time("apply")
for (let i = 0; i<count; i++) {
  range = Array.apply(null, { length: 10 }).map(function(element, index) { return index; })
}
console.timeEnd("apply")


いいね、いいね。ただし、OPが期待する結果は返されません。それを行うには、次のように記述する必要がありますArray.from({length:N}, (v,i) => i+1)
CervEd


16

=>ES6標準の新しい配列メソッドと関数構文を使用する(執筆時点ではFirefoxのみ)。

穴を埋めることによりundefined

Array(N).fill().map((_, i) => i + 1);

Array.from期待どおりに機能するundefinedように「穴」を回しますArray.map

Array.from(Array(5)).map((_, i) => i + 1)

7
同様に、ES6では次のことも実行できますArray.from({length: N}, (v, k) => k)
- XåpplI'-I0llwlg'I

Xappliのアプローチが推奨されます。Array.fromは、このほぼ同じシナリオ用に作成されたものであり、マッピングコールバックを意味します。これArray.prototype.map.callは、から返されるNodeLists など、のような冗長なアプローチに頼らずに、配列のようなものに対してArrayメソッドを使用したいという一般的な問題に対する優れたソリューションdocument.querySelectorAllです。developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
Qaribouからジョシュ

これとアンダースコアの範囲の構文を比較すると、範囲の方が読みやすくなります。
ooolala 2015年

厳密にArray.fromは、スパース値を未定義に変換するのはそうではありません。むしろArray(5)引数オブジェクトとして呼び出され、疎オブジェクトは未定義の値として解釈されます:)
CervEd



12

ES6の場合:

Array.from({length: 1000}, (_, i) => i);

ES5:

Array.apply(0, {length: 1000}).map(function(x,i){return i});

10

ちょうど別のES6バージョン。

Array.from2番目のオプションの引数を使用することにより:

Array.from(arrayLike [、mapFn [、thisArg]])

空のArray(10)位置から番号付き配列を構築できます。

Array.from(Array(10), (_, i) => i)

var arr = Array.from(Array(10), (_, i) => i);
document.write(arr);


これはより複雑であり、〜10倍遅くなり[...Array(11).keys()].slice(1)ます。
Dan Dascalescu 2018

10

現在、このかなり完全な回答リストにない唯一のフレーバーは、ジェネレーターを特徴とするものです。それを改善するには:

const gen = N => [...(function*(){let i=0;while(i<N)yield i++})()]

このように使用できます:

gen(4) // [0,1,2,3]

これの良い点は、インクリメントする必要がないことです... @ igor-shubinが与えた答えからインスピレーションを得るために、ランダムの配列を非常に簡単に作成できます。

const gen = N => [...(function*(){let i=0;
  while(i++<N) yield Math.random()
})()]

そして、次のような長くて運用上高価なものではありません

const slow = N => new Array(N).join().split(',').map((e,i)=>i*5)
// [0,5,10,15,...]

あなたは代わりに行うことができます:

const fast = N => [...(function*(){let i=0;while(i++<N)yield i*5})()]

10

Es6の配列塗りつぶしとマップを使用できます。ちょうどいくつかの人々がこの質問に対して与えた答えで提案したように。以下にいくつかの例を示します。

Example-One: Array(10).fill(0).map((e,i)=>i+1)

Result-One: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Example-Two: Array(100/10).fill(0).map((e,i)=>(i*10)+10)

Result-Two:[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

私はそれが簡単でわかりやすいので、これを好みます。



9

ES6の使用

const generateArray = n => [...Array(n)].map((_, index) => index + 1);

ありがとう!これは私の意見では最もエレガントな答えでした!Array.from(Array(n))スプレッド演算子がサポートされていない場合にも使用できます。
2017年

最初に私にはあなたが広がり演算子を使用しなければならなかった理由を知っているが、その後私は約以下読んでいないmapMDN上:「それは持っている配列の欠けている要素(、設定されたことはありませんインデックス、のために呼び出されていません削除されたか、値が割り当てられていない)。」
battmanz

9

Object.keys(Array.apply(0, Array(3))).map(Number)

を返します[0, 1, 2]イゴールシュビンの優れた答えに非常に似ていますに、トリックが少し少なくなっています(1文字長くなっています)。

説明:

  • Array(3) // [undefined × 3]長さn = 3の配列を生成します。残念ながら、この配列はほとんど役に立たないので、…
  • Array.apply(0,Array(3)) // [undefined, undefined, undefined]配列を反復可能にします。注意:nullは、applyの最初の引数としてより一般的ですが、0の方が短いです。
  • Object.keys(Array.apply(0,Array(3))) // ['0', '1', '2'] 次に、配列のキーを取得します(配列はtypeof配列であるため機能します。配列はキーのインデックスを持つオブジェクトです。
  • Object.keys(Array.apply(0,Array(3))).map(Number) // [0, 1, 2] キーをマッピングし、文字列を数値に変換します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.