Je recherche des alternatives à la ci-dessous pour créer un tableau JavaScript contenant 1 à N où N n'est connu qu'au moment de l'exécution.
var foo = [];
for (var i = 1; i <= N; i++) {
foo.push(i);
}
Pour moi, il semble qu'il devrait y avoir un moyen de le faire sans la boucle.
javascript
arrays
Godders
la source
la source
1 ... N
?Réponses:
Si j'obtiens ce que vous recherchez, vous voulez un tableau de chiffres
1..n
que vous pourrez ensuite parcourir.Si c'est tout ce dont vous avez besoin, pouvez-vous le faire à la place?
puis quand vous voulez l'utiliser ... (non optimisé, juste par exemple)
Par exemple, si vous n'avez pas besoin de stocker quoi que ce soit dans le tableau, vous avez juste besoin d'un conteneur de la bonne longueur sur lequel vous pouvez itérer ... cela pourrait être plus facile.
Voyez-le en action ici: http://jsfiddle.net/3kcvm/
la source
var n = 45;
puis bouclage1..n
ferait l'affaire.foo.length = M
--- L'information de coupure est perdue. Voyez-le en action ==> jsfiddle.net/ACMXpvar n = 45;
.new Array(45);
cela ne "crée pas un tableau à 45 éléments" (au même sens que le[undefined,undefined,..undefined]
fait). Il "crée plutôt un tableau vide de longueur = 45" ([undefined x 45]
), identique àvar foo = []; foo.length=45;
. C'est pourquoiforEach
, etmap
ne s'appliquera pas dans ce cas.Dans ES6, utilisez les méthodes Array from () et keys () .
Version plus courte utilisant l' opérateur d'étalement .
la source
map
au tableau pour ajuster les valeurs ([...Array(10).keys()].map(x => x++);
) pour commencer à 1map(x => x++)
enmap(x => ++x)
raison de l'incrément de priorité qui se produit après le retour de la valeur :)map
quand vous pouvez simplementslice
?[...Array(N+1).keys()].slice(1)
keys
et seulement 1 carte ->Array.from(Array(10)).map((e,i)=>i+1)
from
Array.from(Array(10), (e,i)=>i+1)
Vous pouvez le faire:
ou avec des valeurs aléatoires:
Explication
Tout d'abord, notez que
Number.call(undefined, N)
c'est équivalent àNumber(N)
, qui revient justeN
. Nous utiliserons ce fait plus tard.Array.apply(null, [undefined, undefined, undefined])
est équivalent àArray(undefined, undefined, undefined)
, ce qui produit un tableau à trois éléments et attribueundefined
à chaque élément.Comment pouvez-vous généraliser cela à N éléments? Considérez comment cela
Array()
fonctionne, ce qui ressemble à ceci:Depuis ECMAScript 5 ,
Function.prototype.apply(thisArg, argsArray)
accepte également un objet de type tableau de type canard comme deuxième paramètre. Si nous invoquonsArray.apply(null, { length: N })
, il s'exécuteraNous avons maintenant un tableau à N éléments, chaque élément étant défini sur
undefined
. Lorsque nous l'appellerons.map(callback, thisArg)
, chaque élément sera mis au résultat decallback.call(thisArg, element, index, array)
. Par conséquent,[undefined, undefined, …, undefined].map(Number.call, Number)
mapperait chaque élément à(Number.call).call(Number, undefined, index, array)
, ce qui est le même queNumber.call(undefined, index, array)
, qui, comme nous l'avons observé précédemment, est évalué àindex
. Cela complète le tableau dont les éléments sont les mêmes que leur index.Pourquoi passer par la peine de
Array.apply(null, {length: N})
au lieu de justeArray(N)
? Après tout, les deux expressions résulteraient en un tableau d'éléments N non définis. La différence est que dans la première expression, chaque élément est explicitement défini sur indéfini, tandis que dans la seconde, chaque élément n'a jamais été défini. Selon la documentation de.map()
:Par conséquent,
Array(N)
est insuffisant;Array(N).map(Number.call, Number)
entraînerait un tableau non initialisé de longueur N .Compatibilité
Étant donné que cette technique repose sur le comportement
Function.prototype.apply()
spécifié dans ECMAScript 5, elle ne fonctionnera pas dans les navigateurs pré-ECMAScript 5 tels que Chrome 14 et Internet Explorer 9.la source
Function.prototype.call
le premier paramètre est l'this
objet à mapper directement surArray.prototype.map
le paramètre de l'itérateur a une certaine brillance.map
valeurs non attribuées, à mon avis. Une autre version (et peut-être légèrement plus claire, quoique plus longue) est:Array.apply(null, { length: N }).map(function(element, index) { return index; })
Array.apply(null, new Array(N)).map(function(_,i) { return i; })
ou, en cas de fonctions es6 et flèches, encore plus court:Array.apply(null, new Array(N)).map((_,i) => i)
Plusieurs façons d'utiliser ES6
Utilisation de l'opérateur d'étalement (
...
) et de la méthode des clésRemplir / mapper
Array.from
Array.from et
{ length: N }
piraterRemarque sur le formulaire généralisé
Toutes les formes ci - dessus peuvent produire des tableaux initialisés à des valeurs à peu près tous souhaités en changeant
i+1
l'expression nécessaire (par exemplei*2
,-i
,1+i*2
,i%2
et etc.). Si l'expression peut être exprimée par une fonction,f
la première forme devient simplementExemples:
Puisque le tableau est initialisé avec
undefined
sur chaque position, la valeur dev
seraundefined
Exemple présentant tous les formulaires
Afficher l'extrait de code
Exemple plus générique avec fonction d'initialisation personnalisée, par
f
ex.ou encore plus simple
Afficher l'extrait de code
la source
k++
, utilisez++k
.Les tableaux gèrent de manière innée leurs longueurs. Lorsqu'ils sont parcourus, leurs index peuvent être conservés en mémoire et référencés à ce point. Si un indice aléatoire doit être connu, le
indexOf
méthode peut être utilisée.Cela dit, pour vos besoins, vous pouvez simplement déclarer un tableau d'une certaine taille:
ES6
Propagé
L'utilisation de l'opérateur
...
et de lakeys
méthode spread ( ) vous permet de créer un tableau temporaire de taille N pour produire les index, puis un nouveau tableau qui peut être affecté à votre variable:Remplir / mapper
Vous pouvez d'abord créer la taille du tableau dont vous avez besoin, le remplir avec undefined puis créer un nouveau tableau à l'aide de
map
, qui définit chaque élément sur l'index.Array.from
Cela devrait être l'initialisation à la longueur de taille N et remplir le tableau en un seul passage.
Au lieu des commentaires et de la confusion, si vous vouliez vraiment capturer les valeurs de 1..N dans les exemples ci-dessus, il y a quelques options:
++i
).dans les cas où l'index n'est pas utilisé - et peut-être une manière plus efficace - consiste à créer votre tableau mais à faire N représenter N + 1, puis à décaler le front.
Donc, si vous désirez 100 numéros:
la source
Dans ES6, vous pouvez faire:
Array(N).fill().map((e,i)=>i+1);
http://jsbin.com/molabiluwa/edit?js,console
Edit: Changé
Array(45)
pourArray(N)
depuis que vous avez mis à jour la question.la source
.join.split
version méchante - mais je pense toujours que l'humble boucle est meilleure.map
cela deviendra bientôt un standard pour des choses comme ça.const gen = N => [...(function*(){let i=0;while(i<N)yield i++})()]
.fill()
c'est nécessaire. Je vois que c'est quand je teste sur la repl du nœud, mais depuisArray(1)[0] === undefined
, quelle différence fait l'appel à fill ()Array(1).fill(undefined)
?Utilisez la méthode Underscore _.range très populaire
la source
Puis appelé par
Il n'y a pas de méthode intégrée pour le faire en Javascript, mais c'est une fonction utilitaire parfaitement valide à créer si vous devez le faire plus d'une fois.
Edit: À mon avis, ce qui suit est une meilleure fonction de gamme. Peut-être juste parce que je suis biaisé par LINQ, mais je pense que c'est plus utile dans plus de cas. Votre kilométrage peut varier.
la source
Array
au lieu deArray.prototype
car il n'y a aucune raison (elle pourrait même être considérée comme plutôt stupide) d'avoir cette méthode sur chaque tableau.Array.range(1, 5)
serait probablement plus approprié, mais il y a quelque chose de cool dans l'écriture[].range(1, 5)
.foo = [1, 2, 3]; bar = foo.range(0, 10);
. Mais c'est juste ... déroutant.bar = Array.range(0, 10)
est beaucoup plus clair et explicite. La plage n'a rien à voir avec l'instance, il n'y a donc aucune raison d'en faire une méthode d'instance.le moyen le plus rapide de remplir une
Array
v8 est:le résultat sera:
[0, 1, 2, 3, 4]
la source
Cette question a beaucoup de réponses compliquées, mais une simple ligne:
De plus, bien que ce qui précède soit court (et soigné) à écrire, je pense que ce qui suit est un peu plus rapide (pour une longueur maximale de:
127, Int8,
255, Uint8,
32 767, Int16,
65,535, Uint16,
2.147.483.647, Int32,
4 294 967 295, Uint32.
(basé sur les valeurs entières max ), voici aussi plus sur les tableaux typés ):
Bien que cette solution ne soit pas aussi idéale, car elle crée deux tableaux et utilise la déclaration de variable supplémentaire "$" (je ne sais pas comment contourner cela en utilisant cette méthode). Je pense que la solution suivante est le moyen le plus rapide possible de le faire:
À tout moment après cette instruction, vous pouvez simplement utiliser la variable "arr" dans la portée actuelle;
Si vous voulez en faire une fonction simple (avec quelques vérifications de base):
ainsi, avec la fonction ci-dessus, le "simple one-liner" super-lent ci-dessus devient le super-rapide, encore plus court:
la source
fill
méthode:Array(255).fill(0,0,255)
Vous pouvez utiliser ceci:
par exemple
créera le tableau suivant:
la source
new Array(10).join().split(',').map(function() {return ++arguments[1]});
?join
, une fois poursplit
et une fois pour la chose que vous voulez réellement faire) n'est tout simplement pas agréable - je sais qu'ils semblent être tombés en disgrâce pour une raison quelconque, mais il serait bien préférable d'utiliser simplement une bonne boucle à l' ancienne !ES6, cela fera l'affaire:
Découvrez le résultat:
la source
[...Array(N + 1).keys()].slice(1)
donnera 1..N[...Array(N + 1).keys()]
ce code retourne un tableau vide, mais juste en mode production, l'utilisation du mode développement fonctionne..keys()
réponse a déjà été donnée il y a des années et compte plus de 500 votes positifs. Qu'y ajoute votre réponse?Si vous utilisez d3.js dans votre application comme je le suis, D3 fournit une fonction d'assistance qui le fait pour vous.
Donc, pour obtenir un tableau de 0 à 4, c'est aussi simple que:
et pour obtenir un tableau de 1 à 5, comme vous le demandiez:
Consultez ce tutoriel pour plus d'informations.
la source
Utilisation de l'opérateur d'étalement ES2015 / ES6
la source
i + 1
aurait plus de sens que++i
.C'est probablement le moyen le plus rapide pour générer un tableau de nombres
Le plus court
En ligne
Si vous voulez partir de 1
Vous voulez une fonction?
POURQUOI?
while
est la boucle la plus rapideLe réglage direct est plus rapide que
push
[]
est plus rapide quenew Array(10)
c'est court ... regardez le premier code. puis regardez toutes les autres fonctions ici.
Si vous aimez ne peut pas vivre sans pour
ou
la source
console.time()
pour avoir une intuition, mais pour une preuve, vous avez besoin de jsperf.com ET cela vous montre les résultats de cross-browser d'autres personnes (matériel différent, etc.)var a=[],b=N;while(b--){a[b]=a+1};
Si vous utilisez lodash, vous pouvez utiliser _.range :
Exemples:
la source
la nouvelle façon de remplir
Array
est:le résultat sera:
[0, 1, 2, 3, 4]
la source
avec ES6 vous pouvez faire:
la source
map
etforEach
fonctionneront.Rapport de synthèse final .. Drrruummm Rolll -
Il s'agit du code le plus court pour générer un tableau de taille N (ici 10) sans utiliser ES6 . La version ci-dessus de Cocco est proche mais pas la plus courte.
Mais le vainqueur incontesté de ce golf Code (compétition pour résoudre un problème particulier dans le moins d'octets de code source) est Niko Ruotsalainen . Utilisation de Array Constructor et de l' opérateur d'étalement ES6 . (La plupart de la syntaxe ES6 est du typeScript valide, mais ce n'est pas le cas. Soyez donc judicieux lorsque vous l'utilisez)
la source
a
. La boucle devrait êtrefor(var a=[];n--;a[n]=n+1)
Il y a une autre façon dans ES6, en utilisant Array.from qui prend 2 arguments, le premier est un arrayLike (dans ce cas un objet avec
length
propriété), et le second est une fonction de mappage (dans ce cas, nous mappons l'élément à son index)c'est plus court et peut être utilisé pour d'autres séquences comme la génération de nombres pairs
Cela a également de meilleures performances que la plupart des autres moyens car il ne boucle qu'une seule fois à travers la baie. Vérifiez l'extrait de code pour quelques comparaisons
la source
Array.from({length:N}, (v,i) => i+1)
Utilisation de nouvelles méthodes Array et de la
=>
syntaxe de fonction du standard ES6 (uniquement Firefox au moment de la rédaction).En remplissant les trous avec
undefined
:Array.from
transforme les "trous" enundefined
doncArray.map
fonctionne comme prévu:la source
Array.from({length: N}, (v, k) => k)
.Array.prototype.map.call
, par exemple pour les NodeLists renvoyéesdocument.querySelectorAll
. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…Array.from
ce qui transforme les valeurs clairsemées en indéfinies. PlutôtArray(5)
est appelé comme un objet arguments qui à son tour interprète les valeurs éparses comme des valeurs indéfinies :)la source
[...Array(9)].map((_, i) => i)
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
la source
Dans ES6:
ES5:
la source
Juste une autre version ES6 .
En utilisant le
Array.from
deuxième argument facultatif:Nous pouvons construire le tableau numéroté à partir des
Array(10)
positions vides :la source
[...Array(11).keys()].slice(1)
.Il semble que la seule saveur qui ne figure pas actuellement dans cette liste de réponses plutôt complète est celle qui comprend un générateur; pour y remédier:
qui peut être utilisé ainsi:
La bonne chose à ce sujet est que vous n'avez pas seulement à incrémenter ... Pour vous inspirer de la réponse donnée par igor-shubin, vous pouvez créer un tableau de randoms très facilement:
Et plutôt que quelque chose de
long sur le planopérationnel comme:vous pourriez plutôt faire:
la source
Vous pouvez utiliser le remplissage et la carte du tableau à partir d'Es6; tout comme quelques personnes l'ont suggéré dans les réponses qu'elles ont données à cette question. Voici quelques exemples:
Je préfère cela parce que je le trouve simple et plus facile.
la source
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
la source
Utilisation d'ES6
la source
Array.from(Array(n))
si l'opérateur de propagation n'est pas pris en charge.map
sur MDN : "Il n'est pas appelé pour les éléments manquants du tableau (c'est-à-dire, les index qui n'ont jamais été définis, qui ont été supprimée ou à laquelle aucune valeur n'a été attribuée). "Object.keys(Array.apply(0, Array(3))).map(Number)
Retours
[0, 1, 2]
. Très similaire à l'excellente réponse d' Igor Shubin , mais avec un peu moins de ruse (et un personnage de plus).Explication:
Array(3) // [undefined × 3]
Générez un tableau de longueur n = 3. Malheureusement, ce tableau nous est presque inutile, nous devons donc…Array.apply(0,Array(3)) // [undefined, undefined, undefined]
rendre le tableau itérable. Remarque: null est plus courant que le premier argument de apply mais 0 est plus court.Object.keys(Array.apply(0,Array(3))) // ['0', '1', '2']
puis récupérez les clés du tableau (fonctionne parce que les tableaux sont le type de tableau est un objet avec des index pour les clés.Object.keys(Array.apply(0,Array(3))).map(Number) // [0, 1, 2]
et mappez les clés, convertissant les chaînes en nombres.la source