Vous pouvez le faire :
var N = 10;
Array.apply(null, {length: N}).map(Number.call, Number)
résultat : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].
ou avec des valeurs aléatoires :
Array.apply(null, {length: N}).map(Function.call, Math.random)
résultat : [0.7082694901619107, 0.9572225909214467, 0.8586748542729765, 0.8653848143294454, 0.008339877473190427, 0.9911756622605026, 0.8133423360995948, 0.8377588465809822, 0.5577575915958732, 0.16363654541783035]
Explication
Tout d'abord, notez que Number.call(undefined, N)
est équivalent à Number(N)
qui renvoie simplement N
. Nous utiliserons ce fait plus tard.
Array.apply(null, [undefined, undefined, undefined])
est équivalent à Array(undefined, undefined, undefined)
qui produit un tableau de trois éléments et assigne undefined
à chaque élément.
Comment pouvez-vous généraliser cela à N éléments ? Examinez comment Array()
fonctionne, ce qui donne quelque chose comme ça :
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;
}
Depuis ECMAScript 5 , Function.prototype.apply(thisArg, argsArray)
accepte également un objet de type tableau de type canard comme second paramètre. Si nous invoquons Array.apply(null, { length: N })
alors il exécutera
function Array() {
var a = [];
for (var i = 0; i < /* arguments.length = */ N; i++) {
a.push(/* arguments[i] = */ undefined);
}
return a;
}
Maintenant, nous avons un N -dont chaque élément est défini comme suit undefined
. Lorsque nous appelons .map(callback, thisArg)
sur elle, chaque élément sera défini comme le résultat de callback.call(thisArg, element, index, array)
. Par conséquent, [undefined, undefined, …, undefined].map(Number.call, Number)
mettrait chaque élément en correspondance avec (Number.call).call(Number, undefined, index, array)
qui est identique à Number.call(undefined, index, array)
qui, comme nous l'avons observé plus tôt, est égal à index
. Cela complète le tableau dont les éléments sont identiques à leur indice.
Pourquoi se donner la peine de Array.apply(null, {length: N})
au lieu de simplement Array(N)
? Après tout, les deux expressions donneraient lieu à un N -élément tableau d'éléments non définis. La différence est que dans la première expression, chaque élément est explicitement set à indéfini, alors que dans le second, chaque élément n'a jamais été défini. Selon la documentation de .map()
:
callback
n'est invoqué que pour les index du tableau qui ont des valeurs assignées ; il n'est pas invoqué pour les index qui ont été supprimés ou qui n'ont jamais été assignés.
Par conséquent, Array(N)
est insuffisante ; Array(N).map(Number.call, Number)
résulterait en un tableau non initialisé de longueur N .
Compatibilité
Comme cette technique repose sur le comportement de Function.prototype.apply()
spécifié dans ECMAScript 5, il sera ne fonctionne pas dans les navigateurs pré-ECMAScript 5 tels que Chrome 14 et Internet Explorer 9.
297 votes
Après avoir lu toute cette page, je suis arrivé à la conclusion que votre propre boucle for est la plus simple, la plus lisible et la moins sujette aux erreurs.
0 votes
Si quelqu'un a besoin de quelque chose de plus avancé, j'ai créé une librairie node.js qui fait cela pour les chiffres, les lettres, les plages négatives/positives, etc. github.com/jonschlinkert/fill-range . Il est utilisé dans github.com/jonschlinkert/braces pour l'expansion de l'accolade et github.com/jonschlinkert/micromatch pour les motifs globaux
0 votes
Une autre façon de procéder peut être la suivante : Array.from({length : 10}, (_, v) => v)
0 votes
@SahilGupta Presque. Si nous voulons 1 à 10, nous devons ajouter 1, par exemple ceci : Array.from({length : 10}, (_, v) => v+1)
0 votes
Au lieu d'un tableau, définissez foo comme objet {} puis ajoutez vos propres index avec foo[i] = i ;
0 votes
@SPlatten pourquoi ?
0 votes
@bluejayke, vous n'avez pas besoin de pousser dans le tableau, vous pouvez simplement utiliser i et tester typeof foo[i] == "nombre".
0 votes
Certains d'entre nous font référence à l'utilisation de ce qui n'est pas bon au niveau de la performance : regardez ici stackoverflow.com/a/61997323/13531204