web-dev-qa-db-ja.com

JavaScriptで配列の長さを初期化する方法?

私がJavaScript( w3schools および devguru を含む)で配列について読んだチュートリアルのほとんどは、var test = new Array(4);構文を使用してArrayコンストラクターに整数を渡すことで、一定の長さで配列を初期化できることを示します。 。

私のjsファイルでこの構文を寛大に使用した後、 jsLint を介してファイルの1つを実行し、それがおかしくなりました。

エラー:1行目の文字22に問題があります: ')'が予期されていましたが、 '4'が表示されました。
var test = new Array(4);
1行目の文字23の問題: ';'が必要ですそして代わりに ')'を見ました。
var test = new Array(4);
1行目の文字23の問題:識別子が必要ですが、代わりに ')'が表示されました。

jsLintの動作説明 を読んでみると、jsLintはnew Array()構文にはあまり似ていないように見え、代わりに配列を宣言するときは[]を優先します。

だから私はいくつか質問があります。まず、なぜ?代わりにnew Array()構文を使用して危険を冒していますか?注意すべきブラウザの非互換性はありますか?次に、角括弧の構文に切り替えると、配列を宣言してその長さをすべて1行に設定する方法があります。または、次のようにする必要があります。

var test = [];
test.length = 4;
422
  1. なぜ長さを初期化するのですか?理論的にはこれは必要ありません。 lengthを使用して配列が空であるかどうかを調べるすべてのテストは、配列が空でないことを報告するため、動作が混乱する可能性さえあります。
    Sometests は、大きな配列の初期の長さを設定することを示しますcan 配列が後で満たされる場合はより効率的ですが、パフォーマンスの向上(ある場合)はブラウザーごとに異なるようです。

  2. jsLintはnew Array()を好みません。これは、コンストラクタがあいまいだからです。

    new Array(4);
    

    空の配列を作成します長さ 4。

    new Array('4');
    

    配列を作成します値を含む'4'

コメントについて:JSでは、配列の長さを初期化する必要はありません。それは動的に成長します。長さを何らかの変数に保存することができます。

var data = [];
var length = 5; // user defined length

for(var i = 0; i < length; i++) {
    data.Push(createSomeObject());
}
347
Felix Kling
  • Array(5)は長さ5の配列を与えますが、値は与えないので、それを反復することはできません。

  • Array.apply(null, Array(5)).map(function () {})は、長さ5で値として未定義の配列を返します。これで、配列の繰り返しが可能になりました。

  • Array.apply(null, Array(5)).map(function (x, i) { return i; })は、長さ5、値0、1、2、3、4の配列を返します。

  • Array(5).forEach(alert)は何もしません、Array.apply(null, Array(5)).forEach(alert)はあなたに5つのアラートを与えます

  • ES6は私達にArray.fromを与えるので、今またあなたはArray.from(Array(5)).forEach(alert)を使うことができます

  • あなたが特定の値で初期化したいならば、これらは知っているのが良いです...
    Array.from('abcde')Array.from('x'.repeat(5))
    またはArray.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]

425
Ruben Stolk

ES2015.fill() を使用すると、簡単に実行できます。

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

これはArray.apply(0, new Array(n)).map(i => value)よりずっと簡潔です

.fill()0をドロップして引数なしで実行すると、配列にundefinedが入ります。 ( ただし、TypeScriptでは失敗します

185
AP.

最も短い:

[...Array(1000)]
53

ES6では Array.from が導入され、 "array-like" または iterables オブジェクトからArrayを作成できます。

Array.from({length: 10}, (x, i) => i);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

この場合、{length: 10}は、 "array-like" objectの最小定義を表します。これは、lengthプロパティのみが定義された空のオブジェクトです。

Array.from は、結果の配列をマップするための2番目の引数を許可します。

32
[...Array(6)].map(x=>0);

// [0, 0, 0, 0, 0, 0]

_または_

Array(6).fill(0);

// [0, 0, 0, 0, 0, 0]

注:空のスロットをループすることはできませんArray(4).forEach( (_,i) => {} )

_または_

Array(6).fill(null).map( (x,i) => i );

// [0, 1, 2, 3, 4, 5]

TypeScriptセーフ


入れ子になった配列の作成

fill 2D 配列を直感的に作成するときは、新しいインスタンスを作成する必要があります。しかし実際には、同じ配列が参照として格納されます。

var a = Array(3).fill([6]); 
// [[6], [6], [6]]

a[ 0 ].Push( 9 );
// [[6,9], [6,9], [6,9]]

溶液

var a = [...Array(3)].map(x=>[]); 

a[ 0 ].Push( 4, 2 );
// [[4,2], [ ], [ ]]

したがって、3x2の配列はこのようになります。

[...Array(3)].map(x=>Array(2).fill(0));

// [ [0,0] ,
//   [0,0] ,
//   [0,0] ]
31
Vlad

これはlengthプロパティを4に初期化します。

var x = [,,,,];
24
Šime Vidas

1行で長さを設定できる機能的な解決策が提案されていないのは驚きです。以下はUnderscoreJSに基づいています。

var test = _.map(_.range(4), function () { return undefined; });
console.log(test.length);

上記の理由から、配列を特定の値に初期化したいのでなければ、これを避けることができます。興味深いことに、Lo-dashやLazyなど、rangeを実装しているライブラリは他にもありますが、これらには異なるパフォーマンス特性があります。

16
christang

(これはおそらくコメントとしては良かったのですが、長すぎました)

それで、これを読んだ後、私は事前割り当てが実際に速いかどうかに興味がありました。理論的にはそうすべきだからです。しかしながら、このブログはそれに対して助言するいくつかの助言を与えました http://www.html5rocks.com/en/tutorials/speed/v8/

まだわからないので、私はそれをテストにかけました。そして結局のところ、実際には遅くなるようです。

var time = Date.now();
var temp = [];
for(var i=0;i<100000;i++){
    temp[i]=i;
}
console.log(Date.now()-time);


var time = Date.now();
var temp2 = new Array(100000);
for(var i=0;i<100000;i++){
    temp2[i] = i;
}
console.log(Date.now()-time); 

このコードは、何度か実行した後に次のようになります。

$ node main.js 
9
16
$ node main.js 
8
14
$ node main.js 
7
20
$ node main.js 
9
14
$ node main.js 
9
19
8
j03m
var arr=[];
arr[5]=0;
alert("length="+arr.length); // gives 6
7
user1067305

人々があなたの古い習慣をまだあきらめないでください。一度メモリを割り当ててからその配列内のエントリを処理すること(古い時点)と、配列が大きくなるにつれて何度も割り当てることとの間には速度の大きな違いがあります。 。

あなたがより大きなアレイで何かクールなことをしたいと思うまではもちろん、これは重要ではありません。それはします。

現時点ではまだ配列の初期容量を設定するためのオプションがないように思われるので、私は以下を使用します...

var newArrayWithSize = function(size) {
  this.standard = this.standard||[];
  for (var add = size-this.standard.length; add>0; add--) {
   this.standard.Push(undefined);// or whatever
  }
  return this.standard.slice(0,size);
}

関係するトレードオフがあります。

  • このメソッドは、関数への最初の呼び出しに他のメソッドと同じぐらい時間がかかりますが、後の呼び出しにはほとんど時間がかかりません(より大きな配列を要求しない限り)。
  • standard配列は、あなたが要求した最大の配列と同じ大きさのスペースを永久に確保します。

しかしそれがあなたがしていることに合うならば、そこに利益があるかもしれません。非公式のタイミング

for (var n=10000;n>0;n--) {var b = newArrayWithSize(10000);b[0]=0;}

かなり速い(n = 1000000の場合、約5秒かかることを考えると、10000で約50ms)

for (var n=10000;n>0;n--) {
  var b = [];for (var add=10000;add>0;add--) {
    b.Push(undefined);
  }
}

1分をはるかに超えて(同じクロムコンソールの10000で約90秒、または約2000倍遅くなります)。それは割り当てだけではなく、10000プッシュ、forループなどにもなります。

6
wils

これは別の解決策です

var arr = Array.apply( null, { length: 4 } );
arr;  // [undefined, undefined, undefined, undefined] (in Chrome)
arr.length; // 4

apply()の最初の引数はthisオブジェクトのバインディングです。これについてはここでは気にしないので、それをnullに設定します。

Array.apply(..)Array(..)関数を呼び出し、その引数として{ length: 3 }オブジェクト値を展開しています。

6
zangw

配列コンストラクタは あいまいな構文 を持ち、JSLintは結局あなたの気持ちを傷つけます。

また、あなたのサンプルコードは壊れています、2番目のvarステートメントはSyntaxErrorを上げます。配列lengthのプロパティtestを設定しているので、別のvarは必要ありません。

あなたの選択に関する限り、array.lengthは唯一の「きれいな」ものです。問題は、なぜそもそもサイズを設定する必要があるのですか?その依存関係を取り除くためにコードをリファクタリングしてみてください。

3
Ivo Wetzel

配列の長さが一定であると仮定します。 Javascriptでは、これが私たちの行動です。

const intialArray = new Array(specify the value);

2
mohan babu

上で説明したように、new Array(size)を使うことはいくぶん危険です。直接使うのではなく、「配列作成関数」の中に置いてください。この関数にバグがないことを簡単に確認でき、new Array(size)を直接呼び出す危険性を回避できます。また、オプションのデフォルト初期値を指定することもできます。このcreateArray関数はまさにそれを行います。

function createArray(size, defaultVal) {
    var arr = new Array(size);
    if (arguments.length == 2) {
        // optional default value
        for (int i = 0; i < size; ++i) {
            arr[i] = defaultVal;
        }
    }
    return arr;
}
1
Domi

new Arrayを使用してはいけない理由は、次のコードで実証されています。

var Array = function () {};

var x = new Array(4);

alert(x.length);  // undefined...

他のコードArray変数を混乱させる可能性があります。誰かがそのようなコードを書くことになるのは少し先んじていますが、それでも...

また、Felix Kingが言ったように、インタフェースは少し矛盾していて、追跡するのが非常に難しいバグを引き起こす可能性があります。

new Array(x)のように)未定義値で埋められた、length = xの配列が欲しいなら、これを行うことができます:

var x = 4;
var myArray = [];
myArray[x - 1] = undefined;

alert(myArray.length); // 4
0
nickf