Initialisieren eines Arrays mit einem einzelnen Wert

Antworten:

43
while(arraySize--) array.push(value);

keine Initialisierung (die ich kenne)


Aktualisieren

Seit wir diese Antwort vor 4 Jahren veröffentlicht haben, scheinen die Leute immer wieder hierher zu kommen, um diese Antwort zu erhalten. Für Benchmarking-Zwecke habe ich einen JSPerf mit verschiedenen Lösungen erstellt.

Die obige Lösung ist nicht die schnellste, obwohl sie kurz ist. Um am gleichen kurzen Stil festzuhalten, aber mit einer besseren Leistung:

while(size--) array[size] = value;

Update Feb 2016 Aktualisiert die JSPerf mit einer neuen Revision mit mehr Testfällen.

Wenn Leistung keine Rolle spielt und Sie einen Einzeiler wünschen:

var value = 1234, // can be replaced by a fixed value
    size  = 1000, // can be replaced by a fixed value
    array = Array.apply(null,{length: size}).map(function() { return value; });

Eine leistungsfähigere Lösung (in einer, schmutzigen, Zeile): Beachten Sie: Dies ersetzt vorhandene Variablen für Wert, Größe und i im Bereich

for(var i = 0, value = 1234, size = 1000, array = new Array(1000); i < size; i++) array[i] = value;
DoXicK
quelle
In vielen Fällen wäre "arraySize" nicht veränderbar (könnte eine Konstante oder ein Literal sein oder - ich weiß, schlechte Praxis - "array.length"). Durch die Darstellung der Größe als Variable habe ich dieses Bit unklar gemacht.
ältester lebender Junge
1
true: "for (var i = arraySize; i--;) array.push (value);" dann :-) aber ich denke du hast das schon herausgefunden
DoXicK
1
Sie haben Recht - diese Syntax spart fünf Zeichen. ;-)
ältester lebender Junge
3
whileist 2-mal langsamer als forin JavaScript, und einfache Überprüfungen wie if (number)sind auch langsamer als if (number === 0)aufgrund der Typkonvertierung (dies gilt auch für Boolesche Werte, Zeichenfolgen und Nullen). Meine jsPerf-Tests haben mir das beigebracht.
Triang3l
2
neues Array (len) .fill (0);
Muhammad Umer
128

Ein kurzer Weg wäre:

var arr = Array(arraySize).fill(value);

Würde machen arr = Array [ 0, 0, 0, 0, 0 ]wenn arraySize == 5und value == 0zum Beispiel.

Klaus Byskov Pedersen
quelle
2
Perry
22
@Perry. Sie wissen, wenn der Browser mit 6% des Marktes den Standard nicht unterstützt, ist es das Problem dieses Browsers
Slava
10
Seien Sie vorsichtig mit der Füllfunktion, wenn der Wert ein Objekt ist, da Sie möglicherweise dasselbe Objekt im gesamten Array haben, was zu unerwünschten Ergebnissen führen kann.
Gregzenegair
12

Ich finde das schön, kurz und elegant:

// assuming `value` is what you want to fill the array with
// and `arraySize` is the size of the array
Array(arraySize).fill(value);
magikMaker
quelle
9

Das OP scheint nach Kompaktheit in einem Einweg-Szenario über Effizienz und Wiederverwendbarkeit zu streben. Für andere, die Effizienz suchen, ist hier eine Optimierung, die noch nicht erwähnt wurde. Da Sie die Länge des Arrays im Voraus kennen, legen Sie sie fest, bevor Sie die Werte zuweisen. Andernfalls wird die Größe des Arrays im laufenden Betrieb wiederholt geändert - nicht ideal!

function initArray(length, value) {
    var arr = [], i = 0;
    arr.length = length;
    while (i < length) { arr[i++] = value; }
    return arr;
}

var data = initArray(1000000, false);
Aequitas
quelle
1
In JavaScript forist 2 mal schneller als while.
Triang3l
2
Ich würde nicht sagen, dass es so genau ist: stoimen.com/blog/2012/01/24/javascript-performance-for-vs-while Sicherlich möchten Sie auch nicht immer beide exklusiv verwenden - das macht ihren Zweck zunichte . Es sollte die Aufgabe des Dolmetschers / Compilers sein, es zu beschleunigen, wo es kann, nicht Ihre. Aber auch das stimmt nicht immer.
Aram Kocharyan
8

Dies ist nicht so kompakt, aber wohl direkter.

array = Array.apply(null, new Array(arraySize)).map(function () {return value;});
Christopher Weiss
quelle
5

Dies ist wahrscheinlich nicht besser als eine der oben genannten Techniken, aber es macht Spaß ...

var a = new Array(10).join('0').split('').map(function(e) {return parseInt(e, 10);})
Christopher Weiss
quelle
Können Sie erklären, warum var arr = (new Array(5)).map(() => 1);es nicht funktioniert?
Bharat Gupta
1
Die map () -Methode funktioniert nur mit Werten im Array. Es überspringt undefinierte Elemente.
Christopher Weiss
So nach , new Array(5)wenn wir eine Karte tun sind wir nicht auf einem Array in Betrieb? Auch dies [1,undefined,3].map(() => 5)funktioniert wie erwartet. Es überspringt nichtundefined
Bharat Gupta
2
Aus der Mozilla-Dokumentation unter developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… : map ruft eine bereitgestellte Rückruffunktion einmal für jedes Element in einem Array in der angegebenen Reihenfolge auf und erstellt aus den Ergebnissen ein neues Array . Der Rückruf wird nur für Indizes des Arrays aufgerufen, denen Werte zugewiesen wurden, einschließlich undefinierter Werte. Es wird nicht für fehlende Elemente des Arrays aufgerufen (dh Indizes, die nie festgelegt wurden, die gelöscht wurden oder denen noch nie ein Wert zugewiesen wurde).
Christopher Weiss
Genial. Danke @Christopher!
Bharat Gupta
4

Dies ist eine alte Frage, aber ich verwende sie in modernen JS:

[...new Array(1000000)].map(()=>42);
Rick Love
quelle
2

Aus Effizienzgründen würde ich vermeiden push. Also einfach

for (var i = 0; i < arraySize; i++) array[i] = value; 

Für IE10:

array = new Array(arraySize); 
for (var i = 0; i < arraySize; i++) array[i] = value; 

Bearbeiten: geändert wie in den Kommentaren beschrieben.

Kyaw Tun
quelle
for (var i = 0; i < arraySize; ++i)hat fast die gleiche Leistung wie Ihr Code, sieht aber sauberer aus. Ist while (arraySize--)aber 2 mal langsamer.
Triang3l
Ja, aber die Speicherzuweisung für arrayist effektiver als das Starten array[0].
Kyaw Tun
2
Nein. Wenn Sie ab Ende mit der Initialisierung eines Arrays beginnen, werden Hash-Tabellen intern verwendet. Wenn Sie jedoch mit der Initialisierung eines Arrays ab 0 beginnen und nur sequentielle Indizes haben, wird ein echtes Array verwendet (zumindest in V8). JavaScript weist keine (höchster_index + 1) Elemente zu, sondern nur initialisierte Elemente.
Triang3l
Ab [Build / 12] ( channel9.msdn.com/Events/Build/2012/4-000 ) muss IE10 vorab zugewiesen werden, um effizient zu sein. Ref [auf Folie 54] ( channel9.msdn.com/Events/Build/2012/4-000 )
Kyaw Tun
1

Wenn Sie dies mehrmals tun müssen, können Sie jederzeit eine Funktion schreiben:

function makeArray(howMany, value){
    var output = [];
    while(howMany--){
        output.push(value);
    }
    return output;
}

var data = makeArray(40, "Foo");

Und nur der Vollständigkeit halber (das Herumspielen mit dem Prototyp von eingebauten Objekten ist oft keine gute Idee):

Array.prototype.fill = function(howMany, value){
    while(howMany--){
        this.push(value);
    }
}

So können Sie jetzt:

var data = [];
data.fill(40, "Foo");

Update: Ich habe gerade Ihre Notiz über arraySizeeine Konstante oder ein Literal gesehen. Wenn ja, ersetzen Sie einfach alle while(howMany--)durch gute alte for(var i=0; i<howMany; i++).

Álvaro González
quelle
1

Stolperte über dieses, während ich Array-Methoden in einem Flugzeug erforschte. Ohhh, die Orte, an die wir gehen, wenn wir gelangweilt sind. :) :)

var initializedArray = new Array(30).join(null).split(null).map(function(item, index){
  return index;
});

.map()und nullfür den Sieg! Ich mag null, weil das Übergeben eines Strings wie oben mit '0' oder einem anderen Wert verwirrend ist. Ich denke, das ist deutlicher, dass wir etwas anderes machen.

Beachten Sie, dass .map()nicht initialisierte Werte übersprungen werden. Deshalb new Array(30).map(function(item, index){return index});funktioniert das nicht. Die neue .fill()Methode wird bevorzugt, sofern verfügbar. Die Browserunterstützung sollte jedoch ab sofort beachtet werden 23.08.2015 beachtet werden .

Desktop (Basisunterstützung)

  • Chrome 45 (36 1 )
  • Firefox (Gecko) 31 (31)
  • Internet Explorer Nicht unterstützt
  • Opera Wird nicht unterstützt
  • Safari 7.1

Von MDN :

[1, 2, 3].fill(4);               // [4, 4, 4]
[1, 2, 3].fill(4, 1);            // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);         // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);       // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN);     // [1, 2, 3]
Array(3).fill(4);                // [4, 4, 4]
[].fill.call({ length: 3 }, 4);  // {0: 4, 1: 4, 2: 4, length: 3}
Joshua Robinson
quelle
Dies kann heutzutage (Juni 2019) leicht geschrieben werden als: [...Array(30)].map((_, i) => i);
magikMaker