Jak zainicjalizować długość tablicy w JavaScript?
Większość samouczków, które czytałem o tablicach w JavaScript (w tym w3schools i devguru) sugeruje, że można zainicjować tablicę o określonej długości, przekazując liczbę całkowitą do konstruktora tablicy przy użyciu składni var test = new Array(4);
.
Po użyciu tej składni w moich plikach js, przepuściłem jeden z plików przez jsLint i wyszło:
Error: Problem at line 1 character 22: Expected') ' and instead saw '4'.
var test = new Array (4);
Problem w linii 1 znak 23: Expected'; 'and instead saw')'.
var test = new Array (4);
Problem w linii 1 znak 23: oczekiwał identyfikatora, a zamiast tego zobaczył")".
Po przeczytaniu wyjaśnienia jslinta jego zachowania, wygląda na to, że jsLint nie lubi składni new Array()
, a zamiast tego preferuje []
podczas deklarowania tablic.
Więc mam kilka pytań:
Po pierwsze, dlaczego? Czy Ja uruchamianie jakiegokolwiek ryzyka używając zamiast tego składninew Array()
? Czy są niezgodności w przeglądarce, o których powinienem wiedzieć?
I po drugie, jeśli przełączę się na składnię nawiasu kwadratowego, czy jest jakiś sposób na zadeklarowanie tablicy i ustawienie jej długości w jednej linii, Czy muszę zrobić coś takiego:
var test = [];
test.length = 4;
18 answers
Dlaczego chcesz zainicjować długość? Teoretycznie nie ma takiej potrzeby. Może to nawet spowodować mylące zachowanie, ponieważ wszystkie testy, które używają
length
, aby dowiedzieć się, czy tablica jest pusta, będą raportować, że tablica nie jest pusta.
niektóre testy pokazują, że ustawienie początkowej długości dużych tablic Może być bardziej efektywne, jeśli tablica zostanie później wypełniona, ale przyrost wydajności (jeśli występuje) wydaje się różnić w zależności od przeglądarki przeglądarka.-
JsLint nie lubi
new Array()
, ponieważ konstruktor jest niejednoznaczny.new Array(4);
Tworzy pustą tablicę o długości 4. Ale
new Array('4');
Tworzy tablicę zawierającą wartość
'4'
.
Odnośnie Twojego komentarza: w JS nie musisz inicjalizować długości tablicy. Rośnie dynamicznie. Możesz po prostu zapisać długość w jakiejś zmiennej, np.
var data = [];
var length = 5; // user defined length
for(var i = 0; i < length; i++) {
data.push(createSomeObject());
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-07 15:21:01
Array(5)
daje tablicę o długości 5, ale bez wartości, dlatego nie można nad nią iteracji.Array.apply(null, Array(5)).map(function () {})
daje tablicę o długości 5 i undefined jako wartości, teraz Można ją iterować.Array.apply(null, Array(5)).map(function (x, i) { return i; })
daje tablicę o długości 5 i wartościach 0,1,2,3,4.-
Array(5).forEach(alert)
nic nie robi,Array.apply(null, Array(5)).forEach(alert)
daje 5 wpisów ES6
daje namArray.from
, więc teraz możesz również użyćArray.from(Array(5)).forEach(alert)
Jeśli chcesz inicjalizuj z pewną wartością, dobrze jest to wiedzieć...
Array.from('abcde')
,Array.from('x'.repeat(5))
lubArray.from({length: 5}, (v, i) => i) // gives [0, 1, 2, 3, 4]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-11 14:01:52
Z ES2015 .fill()
możesz teraz po prostu zrobić:
// `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)
Który jest o wiele bardziej zwięzły niż Array.apply(0, new Array(n)).map(i => value)
Można upuścić 0
w .fill()
i uruchomić bez argumentów, które wypełnią tablicę undefined
. ( to jednak nie powiedzie się w maszynopisie )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-09 21:59:35
[...Array(6)].map(x => 0);
// [0, 0, 0, 0, 0, 0]
Lub
Array(6).fill(0);
// [0, 0, 0, 0, 0, 0]
uwaga: nie można zapętlać pustych slotów tj. Array(4).forEach(() => …)
Lub
( typescript safe )
Array(6).fill(null).map((_, i) => i);
// [0, 1, 2, 3, 4, 5]
Lub
Klasyczna metoda wykorzystująca funkcję (działa w dowolnej przeglądarce)
function NewArray(size) {
var x = [];
for (var i = 0; i < size; ++i) {
x[i] = i;
}
return x;
}
var a = NewArray(10);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Tworzenie zagnieżdżonych tablic
Podczas tworzenia 2D tablica z fill
intuicyjnie powinna tworzyć nowe instancje. Ale to, co faktycznie się wydarzy, to ta sama tablica będą przechowywane jako odniesienie.
var a = Array(3).fill([6]);
// [ [6], [6], [6] ]
a[0].push(9);
// [ [6, 9], [6, 9], [6, 9] ]
Rozwiązanie
var a = [...Array(3)].map(x => []);
a[0].push(4, 2);
// [ [4, 2], [], [] ]
Więc tablica 3x2 będzie wyglądać mniej więcej tak:
[...Array(3)].map(x => Array(2).fill(0));
// [ [0, 0], [0, 0], [0, 0] ]
Tablica N-wymiarowa
function NArray(...dimensions) {
var index = 0;
function NArrayRec(dims) {
var first = dims[0], next = dims.slice().splice(1);
if(dims.length > 1)
return Array(dims[0]).fill(null).map((x, i) => NArrayRec(next ));
return Array(dims[0]).fill(null).map((x, i) => (index++));
}
return NArrayRec(dimensions);
}
var arr = NArray(3, 2, 4);
// [ [ [ 0, 1, 2, 3 ] , [ 4, 5, 6, 7] ],
// [ [ 8, 9, 10, 11] , [ 12, 13, 14, 15] ],
// [ [ 16, 17, 18, 19] , [ 20, 21, 22, 23] ] ]
Zainicjalizuj szachownicę
var Chessboard = [...Array(8)].map((x, j) => {
return Array(8).fill(null).map((y, i) => {
return `${String.fromCharCode(65 + i)}${8 - j}`;
});
});
// [ [A8, B8, C8, D8, E8, F8, G8, H8],
// [A7, B7, C7, D7, E7, F7, G7, H7],
// [A6, B6, C6, D6, E6, F6, G6, H6],
// [A5, B5, C5, D5, E5, F5, G5, H5],
// [A4, B4, C4, D4, E4, F4, G4, H4],
// [A3, B3, C3, D3, E3, F3, G3, H3],
// [A2, B2, C2, D2, E2, F2, G2, H2],
// [A1, B1, C1, D1, E1, F1, G1, H1] ]
Wartości wypełnione matematycznie
Poręczne małe przeciążenie metody podczas pracy z matematyką
function NewArray( size , method, linear )
{
method = method || ( i => i );
linear = linear || false;
var x = [];
for( var i = 0; i < size; ++i )
x[ i ] = method( linear ? i / (size-1) : i );
return x;
}
NewArray( 4 );
// [ 0, 1, 2, 3 ]
NewArray( 4, Math.sin );
// [ 0, 0.841, 0.909, 0.141 ]
NewArray( 4, Math.sin, true );
// [ 0, 0.327, 0.618, 0.841 ]
var pow2 = ( x ) => x * x;
NewArray( 4, pow2 );
// [ 0, 1, 4, 9 ]
NewArray( 4, pow2, true );
// [ 0, 0.111, 0.444, 1 ]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-30 15:43:47
Najkrótszy:
let arr = [...Array(10)];
console.log(arr);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-28 14:37:24
ES6 wprowadza Array.from
co pozwala na tworzenie Array
z dowolnego"array-like" lubiterables obiektów:
Array.from({length: 10}, (x, i) => i);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
W tym przypadku {length: 10}
reprezentuje minimalną definicję "array-like" obiektu: pustego obiektu o zdefiniowanej właściwości length
.
Array.from
pozwala na odwzorowanie drugiego argumentu nad wynikową tablicą.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-28 11:26:59
Spowoduje zainicjalizowanie właściwości length na 4:
var x = [,,,,];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-31 14:35:14
Dziwię się, że nie zaproponowano funkcjonalnego rozwiązania, które pozwala ustawić długość w jednej linii. Na podstawie podkreślenia opiera się:
var test = _.map(_.range(4), function () { return undefined; });
console.log(test.length);
Z powodów wymienionych powyżej, unikałbym tego, chyba że chciałem zainicjować tablicę do określonej wartości. Warto zauważyć, że istnieją inne biblioteki implementujące range, w tym Lo-dash i Lazy, które mogą mieć różne charakterystyki wydajności.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-23 04:31:44
Oto inne rozwiązanie
var arr = Array.apply( null, { length: 4 } );
arr; // [undefined, undefined, undefined, undefined] (in Chrome)
arr.length; // 4
Pierwszym argumentem {[1] } jest powiązanie z tym obiektem, które nas tu nie obchodzi, więc ustawiamy je na null
.
Array.apply(..)
wywołuje funkcję Array(..)
i rozkłada wartość obiektu { length: 3 }
jako jej argumenty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-31 02:01:30
Proszę ludzi, nie rezygnujcie jeszcze ze swoich starych nawyków. Istnieje duża różnica w szybkości między przydzielaniem pamięci raz, a pracą z wpisami w tej tablicy (jak w starej), a przydzielaniem jej wiele razy w miarę wzrostu tablicy (co jest nieuchronnie tym, co system robi pod maską z innymi sugerowanymi metodami).
Nic z tego nie ma oczywiście znaczenia, dopóki nie chcesz zrobić czegoś fajnego z większymi tablicami. Więc tak jest.
Skoro nadal wydaje się, że nie ma opcji w JS na moment, aby ustawić początkową pojemność tablicy, używam następujących...
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);
}
W grę wchodzą:
- ta metoda zajmuje tyle samo czasu co pozostałe przy pierwszym wywołaniu funkcji, ale bardzo mało czasu na późniejsze wywołania (chyba że poprosi o większą tablicę).
- tablica
standard
trwale rezerwuje tyle miejsca, co największa tablica, o którą prosiłeś.
for (var n=10000;n>0;n--) {var b = newArrayWithSize(10000);b[0]=0;}
W dość szybkim tempie (około 50ms dla 10000 biorąc pod uwagę, że z n=1000000 zajęło to około 5 sekund), i
for (var n=10000;n>0;n--) {
var b = [];for (var add=10000;add>0;add--) {
b.push(undefined);
}
}
W znacznie ponad minutę (około 90 SEK dla 10000 na tej samej konsoli chrome, lub około 2000 razy wolniej). To nie będzie tylko alokacja, ale także 10000 nacisków, pętli for itp..
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-26 01:12:19
(to było chyba lepsze jako komentarz, ale za długo)
Po przeczytaniu tego byłem ciekaw, czy pre-alokacja jest rzeczywiście szybsza, bo teoretycznie powinna być. Jednak ten blog dał kilka wskazówek odradzających to http://www.html5rocks.com/en/tutorials/speed/v8/. Więc wciąż będąc niepewnym, wystawiłem to na próbę. I jak się okazuje, w rzeczywistości wydaje się być wolniejszy.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);
Ten kod daje następujący po kilku przypadkowych uruchomieniach:
$ 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-26 14:25:54
var arr=[];
arr[5]=0;
alert("length="+arr.length); // gives 6
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-27 23:27:03
Zakładając, że długość tablicy jest stała. W Javascript, to jest to, co robimy:
const intialArray = new Array(specify the value);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-23 03:00:32
Konstruktor tablicy ma dwuznaczną składnię , A JSLint po prostu rani twoje uczucia.
Również, Twój przykładowy kod jest uszkodzony, druga var
Instrukcja wywoła SyntaxError
. Ustawiasz właściwość length
tablicy test
, więc nie ma potrzeby stosowania innej var
.
Jeśli chodzi o Twoje opcje, array.length
jest jedynym "czystym". Pytanie brzmi, dlaczego musisz ustawić rozmiar w pierwszej kolejności? Spróbuj przefaktorować kod, aby pozbyć się tej zależności.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-04 11:45:29
Jak wyjaśniono powyżej, używanie new Array(size)
jest nieco niebezpieczne. Zamiast używać go bezpośrednio, umieść go w "funkcji kreatora tablic". Możesz łatwo upewnić się, że ta funkcja jest wolna od błędów i uniknąć niebezpieczeństwa wywołania new Array(size)
bezpośrednio. Możesz również podać opcjonalną domyślną wartość początkową. Ta funkcja createArray
robi dokładnie to:
function createArray(size, defaultVal) {
const arr = new Array(size);
if (defaultVal !== undefined) {
// optional default value
for (let i = 0; i < size; ++i) {
arr[i] = defaultVal;
}
}
return arr;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-29 06:06:36
W większości odpowiedzi zaleca się użycie tablicy fill
, ponieważ w przeciwnym razie "nie można jej iterować", ale to nieprawda. Możesz iterować pustą tablicę, ale nie za pomocą forEach
. Podczas gdy pętle, dla pętli i dla i pętle działają dobrze.
const count = Array(5);
Nie działa.
console.log('---for each loop:---');
count.forEach((empty, index) => {
console.log(`counting ${index}`);
});
Te prace:
console.log('---for of loop:---');
for (let [index, empty] of count.entries()) {
console.log(`counting for of loop ${index}`);
}
console.log('---for i loop:---');
for (let i = 0, il = count.length; i < il; ++i) {
console.log(`counting for i loop ${i}`);
}
console.log('---while loop:---');
let index = 0;
while (index < count.length) {
console.log(`counting while loop ${index}`);
index++;
}
Sprawdź this fiddle z powyższymi przykładami.
Również angulars *ngFor
działa dobrze z pustą tablicą:
<li *ngFor="let empty of count; let i = index" [ngClass]="
<span>Counting with *ngFor {{i}}</span>
</li>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-26 09:32:46
Możesz ustawić długość tablicy używając array.length = youValue
Tak by było
var myArray = [];
myArray.length = yourValue;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-09 19:33:00
Powód, dla którego nie powinieneś używać new Array
jest pokazany w tym kodzie:
var Array = function () {};
var x = new Array(4);
alert(x.length); // undefined...
Inny kod mógłby pomieszać ze zmienną Array. Wiem, że to trochę naciągane, że ktoś napisze taki kod, ale i tak...
Ponadto, jak powiedział Felix King, interfejs jest trochę niespójny i może prowadzić do bardzo trudnych do wyśledzenia błędów.
Jeśli chcesz tablicę o długości = x, wypełnioną undefined( jak zrobiłby new Array(x)
), możesz to zrobić:
var x = 4;
var myArray = [];
myArray[x - 1] = undefined;
alert(myArray.length); // 4
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-31 14:34:15