2016-05-27 15 views
0

Ich habe versucht, new Array() Konstruktor mit map zu verwenden, um einen einzeiligen Code zu erstellen, der eine Liste der Elemente erstellt. Etwas wie folgt aus:Verwenden von Array.map mit neuen Array-Konstruktor

let arr = new Array(12).map((el, i) => { 
 
    console.log('This is never called'); 
 
    return i + 1; 
 
});

Lesen docs, macht das Verhalten Sinn.

Grundsätzlich sagen Docs, dass Callback der Karte auch für deklarierte undefinierte Werte in Array ausgeführt wird, aber nicht zum Beispiel beim Erstellen leerer Arrays wie der Code zuvor.

dies sollte also funktionieren:

var arr = new Array(12); 
 

 
for(let i = 0; i < arr.length ; i++){ 
 
    arr[i] = undefined; 
 
} 
 

 
let list = arr.map((e, i) => { 
 
    console.log(i + 1); 
 
    return i + 1; 
 
});

So können wir auch etwas tun:

let newArray = (length) => { 
 
    let myArray = new Array(length); 
 
    for(let i = 0; i < length; i++) myArray[i] = undefined; 
 
    return myArray; 
 
}; 
 

 
console.log(newArray(12).map((el, i) => i + 1));

Also meine Frage. Gibt es einen besseren/schönen Weg, dies mit der Kartenfunktion zu tun?

Vielen Dank im Voraus!

Antwort

2

Sie können Array#from verwenden, um ein Array zu erstellen, dessen Länge überschritten wurde.

Array.from({length: 12}, (e, i) => i + 1); 
+0

Ziemlich cool! Ich werde Arra auslesen. Danke für diese nützliche Antwort! Antwort wird in 9 Minuten markiert! =) –

+0

Ich bin nicht der Wähler, aber ich würde darauf hinweisen, dass 'Array.from' einen Callback akzeptiert, der sich wie' .map() 'verhält. Wenn Sie das verwenden, erstellen Sie kein unnötiges Zwischenarray. –

+0

Ich weiß es nicht. Ich habe dich aufgewertet. Ich denke, ist ziemlich cool, also werde ich diese Antwort markieren, weil es sauberer ist und für mich arbeitet. Und war der Erste. =) –

1

Section 22.1.3.15 von the spec bekommt man mit der letzten Zeile NOTE 1:

callbackfn nur für Elemente des Arrays aufgerufen wird, die tatsächlich existieren; Es wird nicht für fehlende Elemente des Arrays aufgerufen.

Dieses Verhalten wird durch filter geteilt, forEach, und die anderen funktionalen Methoden.

Der Array-Konstruktor, den Sie aufrufen, Array(len) von section 22.1.1.2, wird die Länge des Arrays festlegen, aber nicht die Elemente initialisieren. Ich bin mir nicht sicher, wo die Spezifikation definiert, was ein fehlendes Element ist, aber das Array, das von new Array(len) erzeugt wird, sollte passen, und so wird keines der Elemente von map berührt.

+1

Das von 'new Array (n)' erstellte Array enthält ** Löcher ** dh '[undefined × n]' und kann daher nicht mit 'map',' filter', 'forEach' ... iteriert werden ... – Tushar

+0

@Tushar the spec berücksichtigt, dass das Array fehlende Elemente und keine "Löcher" enthält. Es gibt feine Unterschiede zwischen einem Sparse-Array und einem solchen mit unscharfen Elementen. – ssube

+0

Es initialisiert das Array nicht mit 'undefinierten' Werten. Einfach gesagt, das Objekt hat keine Eigenschaften von 0 bis zu welcher Länge auch immer angegeben wurde. – MinusFour

2

Ich mag diesen Ansatz, weil es funktioniert immer noch in ES5:

let arr = Array.apply(null, Array(12)) 
    .map(function (x, i) { 
     return i 
    }); 

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

Da New Array gibt ein Array zurück, die „Löcher“ enthält, verwenden Sie gelten wir da behandelt Löcher gelten als ob sie nicht definiert waren. Dies breitet sich undefiniert über das gesamte Array aus, wodurch es mappbar wird.

+0

Entschuldigung für meinen Mangel an Wissen, aber könnten Sie mir bitte erklären, warum es funktioniert? Was macht Array.apply()? –

+1

@JoseHermosillaRodrigo, ich habe meine Antwort etwas klargestellt. Außerdem finden Sie hier eine Dokumentation zu ['apply'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) – KevBot

2

Sie könnten Array verwenden.apply mit einem Objekt mit der Länge darin.

var array = Array.apply(null, { length: 12 }).map((_, i) => i + 1); 
 
console.log(array);