Question Créer un tableau JavaScript contenant 1 ... N


Je cherche des alternatives à la ci-dessous pour créer un tableau JavaScript contenant 1 à N où N est seulement connu à 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 faire cela sans la boucle.


593
2017-09-19 17:34


origine


Réponses:


Si je reçois ce que vous cherchez, vous voulez un tableau de nombres 1..n que vous pouvez ensuite boucler.

Si c'est tout ce dont vous avez besoin, pouvez-vous le faire à la place?

var foo = new Array(45);//create an empty array with length 45

puis quand vous voulez l'utiliser ... (non optimisé, juste par exemple)

for(var i=0;i<foo.length;i++){
  document.write('Item: ' + (i+1) + ' of ' + foo.length + '<br/>'); 
}

par exemple. si vous n'avez pas besoin de le magasin quoi que ce soit dans le tableau, vous avez juste besoin d'un conteneur de la bonne longueur que vous pouvez parcourir ... cela pourrait être plus facile.

Voyez-le en action ici: http://jsfiddle.net/3kcvm/


202
2017-09-19 17:54



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

D'abord, notez que Number.call(undefined, N) est équivalent à Number(N), qui vient de revenir N. Nous utiliserons ce fait plus tard.

Array.apply(null, [undefined, undefined, undefined]) est équivalent à Array(undefined, undefined, undefined), qui produit un tableau à trois éléments et assigne undefined à chaque élément.

Comment pouvez-vous généraliser cela à N éléments? Considérez comment Array() fonctionne, qui va 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 en tant que second paramètre. Si nous invoquons Array.apply(null, { length: N }), alors il va exécuter

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-element array, avec chaque élément défini sur undefined. Quand nous appelons .map(callback, thisArg) dessus, chaque élément sera mis au résultat de callback.call(thisArg, element, index, array). Donc, [undefined, undefined, …, undefined].map(Number.call, Number) cartographierait chaque élément (Number.call).call(Number, undefined, index, array), qui est le même que Number.call(undefined, index, array), qui, comme nous l'avons observé précédemment, évalue index. Cela termine 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 juste Array(N)? Après tout, les deux expressions entraîneraient un N-element array d'éléments indéfinis. La différence est que dans la première expression, chaque élément est explicitement ensemble à indéfini, alors que dans le dernier, chaque élément n'a jamais été défini. Selon la documentation de .map():

callback est invoqué uniquement pour les index du tableau auquel des valeurs ont été affectées; il n'est pas appelé pour les index qui ont été supprimés ou pour lesquels aucune valeur n'a été affectée.

Donc, Array(N) Est insuffisant; Array(N).map(Number.call, Number) entraînerait un tableau non initialisé de longueur N.

Compatibilité

Puisque cette technique repose sur le comportement de Function.prototype.apply() spécifié dans ECMAScript 5, il sera pas travailler dans les navigateurs pré-ECMAScript 5 tels que Chrome 14 et Internet Explorer 9.


655
2017-11-19 08:33



En ES6 utilisant Array de() et clés() méthodes

Array.from(Array(10).keys())
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Version plus courte en utilisant opérateur de propagation.

[...Array(10).keys()]
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

515
2017-10-26 18:03



Simple et brève façon ES6:

Array.from({length: 5}, (v, k) => k+1); 
// [1,2,3,4,5]

Ainsi :

    Array.from({length: N}, (v, k) => k+1);  
   // [1,2,3,...,N]

const range = (N) => Array.from({length: N}, (v, k) => k+1) ;

console.log(
  range(5)
)


165
2017-07-05 21:38



Dans ES6, vous pouvez faire:

Array(N).fill().map((e,i)=>i+1);

http://jsbin.com/molabiluwa/edit?js,console

Modifier: Modifié Array(45) à Array(N) puisque vous avez mis à jour la question.


125
2017-12-21 03:18



Utilisez le très populaire Underscore _.range méthode

// _.range([start], stop, [step])

_.range(10); // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11); // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5); // => [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1); //  => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
_.range(0); // => []

89
2018-06-26 22:05



Je sais que votre question demande de remplir un tableau numériquement, mais je ne sais pas pourquoi vous voudriez le faire.

Les tableaux gèrent de façon innée leurs longueurs. Comme ils sont traversés, 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:

var foo = new Array(N);   // where N is a positive integer

/* this will create an array of size, N, primarily for memory allocation, 
   but does not create any defined values

   foo.length                                // size of Array
   foo[ Math.floor(foo.length/2) ] = 'value' // places value in the middle of the array
*/


ES6

Propager

Utilisation de l'opérateur de propagation (...) et keys méthode, vous permet de créer un tableau temporaire de taille N pour produire les index, puis un nouveau tableau pouvant être affecté à votre variable:

var foo = [ ...Array(N).keys() ];

Remplir / Carte

Vous pouvez d'abord créer la taille du tableau dont vous avez besoin, le remplir avec undefined puis créer un nouveau tableau en utilisant map, qui définit chaque élément à l'index.

var foo = Array(N).fill().map((v,i)=>i);

70
2017-09-19 18:06



function range(start, end) {
    var foo = [];
    for (var i = start; i <= end; i++) {
        foo.push(i);
    }
    return foo;
}

Puis appelé par

var foo = range(1, 5);

Il n'y a pas de façon intégrée de 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.

function range(start, count) {
    if(arguments.length == 1) {
        count = start;
        start = 0;
    }

    var foo = [];
    for (var i = 0; i < count; i++) {
        foo.push(start + i);
    }
    return foo;
}

58
2017-09-19 17:41



Vous pouvez utiliser ceci:

new Array(/*any number which you want*/)
    .join().split(',')
    .map(function(item, index){ return ++index;})

par exemple

new Array(10)
    .join().split(',')
    .map(function(item, index){ return ++index;})

va créer le tableau suivant:

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

40
2018-03-19 08:17