Je recherche des alternatives au modèle ci-dessous pour la création d'un tableau JavaScript contenant de 1 à N, où N n'est connu qu'à l'exécution.
var foo = [];
for (var i = 1; i <= N; i++) {
foo.Push(i);
}
Pour moi, il me semble qu'il devrait y avoir un moyen de le faire sans boucle.
Si je comprends ce que vous recherchez, vous voulez un tableau de nombres 1..n
que vous pourrez parcourir plus tard.
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 stocker quoi que ce soit dans le tableau, vous avez simplement besoin d'un conteneur de la bonne longueur sur lequel vous pouvez parcourir le contenu ... cela pourrait être plus facile.
Voir en action ici: http://jsfiddle.net/3kcvm/
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]
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 à trois éléments et assigne undefined
à chaque élément.
Comment pouvez-vous généraliser cela aux éléments N? Considérez le fonctionnement de (Array()
}, qui ressemble à ceci:
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 appelons Array.apply(null, { length: N })
, alors il sera exécuté
function Array() {
var a = [];
for (var i = 0; i < /* arguments.length = */ N; i++) {
a.Push(/* arguments[i] = */ undefined);
}
return a;
}
Nous avons maintenant un tableau N -element, chaque élément étant défini sur undefined
. Lorsque nous appelons .map(callback, thisArg)
, chaque élément est défini sur le résultat de callback.call(thisArg, element, index, array)
. Par conséquent, [undefined, undefined, …, undefined].map(Number.call, Number)
mapperait chaque élément sur (Number.call).call(Number, undefined, index, array)
, qui est identique à Number.call(undefined, index, array)
et qui, comme nous l'avons vu 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 le problème de Array.apply(null, {length: N})
au lieu de Array(N)
? Après tout, les deux expressions donneraient un tableau N -element d'éléments non définis. La différence est que, dans la première expression, chaque élément est explicitement set sur indéfini, alors que dans la dernière, chaque élément n'a jamais été défini. Selon la documentation de .map()
:
callback
n'est appelé que pour les index du tableau auxquels des valeurs ont été assignées; il n'est pas appelé pour les index qui ont été supprimés ou auxquels aucune valeur n'a été attribuée.
Donc, Array(N)
est insuffisant; Array(N).map(Number.call, Number)
donnerait un tableau non initialisé de longueur N.
Étant donné que cette technique repose sur le comportement de Function.prototype.apply()
spécifié dans ECMAScript 5, il sera non opérationnel dans les navigateurs antérieurs à ECMAScript 5 tels que Chrome 14 et Internet Explorer 9.
Dans ES6, utilisez Array from () 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 spread operator .
[...Array(10).keys()]
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
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)
)
Je sais que votre question demande de remplir numériquement un tableau, mais je ne sais pas pourquoi vous voudriez le faire.
Les tableaux gèrent naturellement leurs longueurs. Au fur et à mesure qu'ils sont parcourus, leurs index peuvent être conservés en mémoire et référencés à cet endroit. Si un index aléatoire doit être connu, la méthode indexOf
peut être utilisée.
Ceci étant dit, pour vos besoins, vous voudrez peut-être 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
*/
L'utilisation de l'opérateur spread (...
) et de la méthode keys
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() ];
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 sur l'index.
var foo = Array(N).fill().map((v,i)=>i);
Cela devrait être initialiser à la longueur N et remplir le tableau en un seul passage.
Array.from({ length: N }, (v, i) => i)
Utilisez la très populaire méthode Underscore _.range
// _.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); // => []
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’existe 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 plusieurs fois.
Edit: À mon avis, voici une meilleure fonction de portée. 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;
}
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;})
créera le tableau suivant:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
le moyen le plus rapide de remplir une Array
dans la v8 est:
[...Array(5)].map((_,i) => i);
le résultat sera: [0, 1, 2, 3, 4]
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:
d3.range(5)
[0, 1, 2, 3, 4]
et pour obtenir un tableau de 1 à 5, comme vous le demandiez:
d3.range(1, 5+1)
[1, 2, 3, 4, 5]
Découvrez ce tutoriel pour plus d’informations.
C’est probablement le moyen le plus rapide de générer un tableau de nombres
Le plus court
var a=[],b=N;while(b--)a[b]=b+1;
En ligne
var arr=(function(a,b){while(a--)b[a]=a;return b})(10,[]);
//arr=[0,1,2,3,4,5,6,7,8,9]
Si vous voulez partir du 1
var arr=(function(a,b){while(a--)b[a]=a+1;return b})(10,[]);
//arr=[1,2,3,4,5,6,7,8,9,10]
Vouloir une fonction?
function range(a,b,c){c=[];while(a--)c[a]=a+b;return c}; //length,start,placeholder
var arr=range(10,5);
//arr=[5,6,7,8,9,10,11,12,13,14]
POURQUOI?
while
est la boucle la plus rapide
Le réglage direct est plus rapide que Push
[]
est plus rapide que new Array(10)
c'est court ... regardez le premier code. puis regardez toutes les autres fonctions ici.
Si vous aimez ne pouvez pas vivre sans pour
for(var a=[],b=7;b>0;a[--b]=b+1); //a=[1,2,3,4,5,6,7]
ou
for(var a=[],b=7;b--;a[b]=b+1); //a=[1,2,3,4,5,6,7]
Cette question a beaucoup de réponses compliquées, mais un simple one-liner:
[...Array(255).keys()].map(x => x + 1)
Aussi, 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 également d'autres informations sur Tableaux typés ):
(new Uint8Array(255)).map(($,i) => i + 1);
Bien que cette solution ne soit pas non plus idéale, elle crée deux tableaux et utilise la déclaration de variable supplémentaire "$" (il n’est pas possible de contourner cela avec cette méthode). Je pense que la solution suivante est le moyen le plus rapide possible de le faire:
for(var i = 0, arr = new Uint8Array(255); i < arr.length; i++) arr[i] = i + 1;
À tout moment après cette déclaration, 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):
function range(min, max) {
min = min && min.constructor == Number ? min : 0;
!(max && max.constructor == Number && max > min) && // boolean statements can also be used with void return types, like a one-line if statement.
((max = min) & (min = 0)); //if there is a "max" argument specified, then first check if its a number and if its graeter than min: if so, stay the same; if not, then consider it as if there is no "max" in the first place, and "max" becomes "min" (and min becomes 0 by default)
for(var i = 0, arr = new (
max < 128 ? Int8Array :
max < 256 ? Uint8Array :
max < 32768 ? Int16Array :
max < 65536 ? Uint16Array :
max < 2147483648 ? Int32Array :
max < 4294967296 ? Uint32Array :
Array
)(max - min); i < arr.length; i++) arr[i] = i + min;
return arr;
}
//and you can loop through it easily using array methods if you want
range(1,11).forEach(x => console.log(x));
//or if you're used to pythons `for...in` you can do a similar thing with `for...of` if you want the individual values:
for(i of range(2020,2025)) console.log(i);
//or if you really want to use `for..in`, you can, but then you will only be accessing the keys:
for(k in range(25,30)) console.log(k);
console.log(
range(1,128).constructor.name,
range(200).constructor.name,
range(400,900).constructor.name,
range(33333).constructor.name,
range(823, 100000).constructor.name,
range(10,4) // when the "min" argument is greater than the "max", then it just considers it as if there is no "max", and the new max becomes "min", and "min" becomes 0, as if "max" was never even written
);
la nouvelle façon de remplir Array
est la suivante:
const array = [...Array(5).keys()]
console.log(array)
le résultat sera: [0, 1, 2, 3, 4]
Rapport de synthèse final .. Drrruummm Rolll - _
C'est le code le plus court pour générer un tableau de taille N (ici 10) sans utiliser ES6. La version de Cocco ci-dessus est proche mais pas la plus courte.
(function(n){for(a=[];n--;a[n]=n+1);return a})(10)
Mais le gagnant incontesté de ce code golf (concours visant à 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 ES6 spread. (La majeure partie de la syntaxe de l'ES6 correspond à TypeScript, mais ce n'est pas la suivante. Soyez donc judicieux lorsque vous l'utilisez)
[...Array(10).keys()]
Il y a une autre manière dans ES6, en utilisant Array.from qui prend 2 arguments, le premier est un arrayLike (dans ce cas, un objet avec la propriété length
), et le second est une fonction de mappage (dans ce cas, nous mappons le item à son index)
Array.from({length:10}, (v,i) => i)
ceci est plus court et peut être utilisé pour d'autres séquences comme générer des nombres pairs
Array.from({length:10}, (v,i) => i*2)
En outre, ses performances sont meilleures que celles de la plupart des autres méthodes, car elles ne survivent qu’une seule fois dans le tableau . Vérifiez l’extrait pour quelques comparaisons.
// open the dev console to see results
count = 100000
console.time("from object")
for (let i = 0; i<count; i++) {
range = Array.from({length:10}, (v,i) => i )
}
console.timeEnd("from object")
console.time("from keys")
for (let i =0; i<count; i++) {
range = Array.from(Array(10).keys())
}
console.timeEnd("from keys")
console.time("apply")
for (let i = 0; i<count; i++) {
range = Array.apply(null, { length: 10 }).map(function(element, index) { return index; })
}
console.timeEnd("apply")
Utilisation de nouvelles méthodes Array et de la syntaxe de la fonction =>
à partir du standard ES6 (uniquement Firefox au moment de la rédaction).
En remplissant les trous avec undefined
:
Array(N).fill().map((_, i) => i + 1);
Array.from
transforme les "trous" en undefined
afin que Array.map
fonctionne comme prévu:
Array.from(Array(5)).map((_, i) => i + 1)
for(var i,a=[i=0];i<10;a[i++]=i);
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Essaye ça:
var foo = [1, 2, 3, 4, 5];
Si vous utilisez CoffeeScript , vous pouvez créer une plage en procédant comme suit:
var foo = [1..5];
Sinon, si vous utilisez JavaScript Vanilla, vous devrez utiliser une boucle si vous souhaitez initialiser un tableau de longueur variable.
Un peu plus simple que la variante de chaîne:
// create range by N
Array(N).join(0).split(0);
// create a range starting with 0 as the value
Array(7).join(0).split(0).map((v, i) => i + 1) // [1, 2, 3, 4, 5, 6, 7]
Mise à jour (1/4/2018): Mise à jour pour répondre à la question exacte du PO. Merci @lessless pour avoir appelé cela!
Il semble que la seule variante qui ne figure pas actuellement dans cette liste de réponses plutôt complète est celle qui comporte un générateur; donc pour remédier à cela:
const gen = N => [...(function*(){let i=0;while(i<N)yield i++})()]
qui peut être utilisé ainsi:
gen(4) // [0,1,2,3]
La bonne chose à ce sujet est qu’il n’est pas seulement nécessaire d’incrémenter ... Pour vous inspirer de la réponse donnée par @ igor-shubin, vous pouvez très facilement créer un tableau d’aléas:
const gen = N => [...(function*(){let i=0;
while(i++<N) yield Math.random()
})()]
Et plutôt que quelque chose longue opérationnellement coûteux comme:
const slow = N => new Array(N).join().split(',').map((e,i)=>i*5)
// [0,5,10,15,...]
vous pourriez plutôt faire:
const fast = N => [...(function*(){let i=0;while(i++<N)yield i*5})()]
La fonction suivante retourne un tableau rempli de nombres:
var createArrayOfNumbers = function (n) {
return Array.apply(null, new Array(n)).map(function (empty, index) {
return index;
});
};
Notez qu'un tableau créé avec le constructeur de tableau est constitué de trous, il ne peut donc pas être traversé avec des fonctions de tableau comme map D'où l'utilisation de la fonction Array.apply
.
Juste une autre version ES6.
En utilisant Array.from
second argument optionnel:
Array.from (arrayLike [ mapFn [ thisArg]])
Nous pouvons construire le tableau numéroté à partir des positions Array(10)
vides:
Array.from(Array(10), (_, i) => i)
var arr = Array.from(Array(10), (_, i) => i);
document.write(arr);
Object.keys(Array.apply(0, Array(3))).map(Number)
Retourne [0, 1, 2]
. Très similaire à excellente réponse d'Igor Shubin , mais avec un peu moins de ruse (et un personnage de plus).
Array(3) // [undefined × 3]
Génère un tableau de longueur n = 3. Malheureusement, ce tableau nous est presque inutile, alors nous devons…Array.apply(0,Array(3)) // [undefined, undefined, undefined]
rend le tableau itérable. Remarque: null est plus commun que le premier argument de apply mais 0 est plus court.Object.keys(Array.apply(0,Array(3))) // ['0', '1', '2']
puis récupère les clés du tableau (fonctionne car les tableaux sont le typeof array est un objet avec des index pour les clés).Object.keys(Array.apply(0,Array(3))).map(Number) // [0, 1, 2]
et mappez sur les clés, convertissant les chaînes en nombres.Utiliser ES6
const generateArray = n => [...Array(n)].map((_, index) => index + 1);
Iterable version en utilisant un générateur fonction qui ne modifie pas Number.prototype
.
function sequence(max, step = 1) {
return {
[Symbol.iterator]: function* () {
for (let i = 1; i <= max; i += step) yield i
}
}
}
console.log([...sequence(10)])
Array(8).fill(0).map(Number.call, Number)
Voler des Igors Number.call
astuce mais en utilisant fill()
pour raccourcir légèrement. Fonctionne uniquement avec ES6 et supérieur.
En improvisant sur ce qui précède:
var range = function (n) {
return Array(n).join().split(',').map(function(e, i) { return i; });
}
on peut obtenir les options suivantes:
1) Array.init à la valeur v
var arrayInitTo = function (n,v) {
return Array(n).join().split(',').map(function() { return v; });
};
2) obtenir une plage inversée:
var rangeRev = function (n) {
return Array(n).join().split(',').map(function() { return n--; });
};
Je recherchais une solution fonctionnelle et je me suis retrouvé avec:
function numbers(min, max) {
return Array(max-min+2).join().split(',').map(function(e, i) { return min+i; });
}
console.log(numbers(1, 9));
Remarque: join().split(',')
transforme le tableau fragmenté en un tableau contigu.
Je n'ai vu aucune solution basée sur des fonctions récursives (et je n'ai jamais écrit de fonctions récursives moi-même), voici donc mon essai.
Notez que array.Push (quelque chose) retourne la nouvelle longueur du tableau:
(a=[]).Push(a.Push(a.Push(0))) // a = [0, 1, 2]
Et avec une fonction récursive:
var a = (function f(s,e,a,n){return ((n?n:n=s)>e)?a:f(s,e,a?a:a=[],a.Push(n)+s)})(start,end) // e.g., start = 1, end = 5
EDIT: deux autres solutions
var a = Object.keys(new Int8Array(6)).map(Number).slice(1)
et
var a = []
var i=setInterval(function(){a.length===5?clearInterval(i):a.Push(a.length+1)})
Vous pouvez utiliser un générateur de fonction ou une fonction * expression . Voici [ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function] Et un référence au lien du générateur de fonctions vers [ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function].
let a = 1, b = 10;
function* range(a, b) {
for (var i = a; i <= b; ++i) yield i;
}
Array.from(range(a, b));
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[...range(a, b)]
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Vous pouvez utiliser Array fill et map from Es6; tout comme quelques personnes suggérées dans les réponses données à cette question. Ci-dessous quelques exemples:
Example-One: Array(10).fill(0).map((e,i)=>i+1)
Result-One: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Example-Two: Array(100/10).fill(0).map((e,i)=>(i*10)+10)
Result-Two:[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
Je préfère cela parce que je le trouve simple et facile.
J'ai trouvé ce vieux fil parce que je m'interrogeais moi-même sur le même sujet, mais je suppose qu'aucune des réponses ici n'a été plus facile que votre exemple initial, a commenté Kokodoko, haha!
J'ai fini par utiliser cette méthode moi-même:
var foo = [];
while (foo.length < N)
foo.Push( foo.length + 1 );
Ce qui est au moins légèrement plus rapide à taper qu'une boucle for normale et, espérons-le, peu sujet aux erreurs (bien que cela puisse coûter plus cher en calcul).
Peut même faire quelque chose comme:
var foo= [];
while (foo.length < N)
foo.Push( foo.length%4 + 1 );
pour remplir le tableau avec 1 à 4 fois multiples dans un ordre séquentiel. Ou utilisez cette méthode pour remplir le tableau avec un seul élément, bien que je suppose que dans ce cas, il serait peut-être plus rapide d’utiliser simplement Array(N).fill(x)
.
Essayez d’ajouter un iterator au prototype de Number.
Number.prototype[Symbol.iterator] = function *(){
let i = 0;
while(i < this) yield i++;
return;
}
Maintenant que les nombres sont éditables, il suffit de passer un numéro à Array.from
Array.from(10);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
ou partout ailleurs, il faut un itératif, comme pour ... des boucles .
for(const number of 10) console.log(number);//logs 0 through 9 sequentially
C'est un peu compliqué, mais aussi cool.
avec ES6 vous pouvez faire:
// `n` is the size you want to initialize your array
// `null` is what the array will be filled with (can be any other value)
Array(n).fill(null)
Partageons le mien: p
var i = 10;
Math.pow(2, i).toString(2).split('').map((i,j) => j)
Version ES5, inefficace, mais peut-être la plus courte est expression, pas une instruction dans laquelle une variable est remplie, par exemple une boucle for
:
(Array(N)+'').split(',').map(function(d,i){return i})
Tout cela est trop compliqué. Il suffit de faire:
function count(num) {
var arr = [];
var i = 0;
while (num--) {
arr.Push(i++);
}
return arr;
}
console.log(count(9))
//=> [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]
Ou pour faire une plage de a
à b
function range(a, b) {
var arr = [];
while (a < b + 1) {
arr.Push(a++);
}
return arr;
}
console.log(range(4, 9))
//=> [ 4, 5, 6, 7, 8, 9 ]
function arrGen(n) {
var a = Array(n)
while (n--) a[n] = n
return a
}
// arrGen(10) => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
// A solution where you do not allocate a N sized array (ES6, with some flow annotation):
function* zeroToN(N /* : number */)/* : Generator<number, void, empty> */ {
for (let n = 0; n <= N; n += 1) yield n;
}
// With this generation, you can have your array
console.log([...zeroToN(10-1)])
// but let's define a helper iterator function
function mapIterator(iterator, mapping) {
const arr = [];
for (let result = iterator.next(); !result.done; result = iterator.next()) {
arr.Push(mapping(result.value));
}
return arr;
}
// now you have a map function, without allocating that 0...N-1 array
console.log(mapIterator(zeroToN(10-1), n => n*n));
La question était pour des alternatives à cette technique mais je voulais partager le plus vite moyen de le faire. Il est presque identique au code de la question, mais il alloue de la mémoire au lieu d'utiliser Push:
function range(n) {
let a = Array(n);
for (let i = 0; i < n; a[i++] = i);
return a;
}
Juste pour m'amuser, je voulais développer la réponse de Ian Henry.
Bien sûr, var array = new Array(N);
vous donnera un tableau de taille N
, mais les clés et les valeurs seront identiques .... alors, pour raccourcir le tableau à la taille M
, utilisez array.length = M
.....
function range()
{
// This function takes optional arguments:
// start, end, increment
// start may be larger or smaller than end
// Example: range(null, null, 2);
var array = []; // Create empty array
// Get arguments or set default values:
var start = (arguments[0] ? arguments[0] : 0);
var end = (arguments[1] ? arguments[1] : 9);
// If start == end return array of size 1
if (start == end) { array.Push(start); return array; }
var inc = (arguments[2] ? Math.abs(arguments[2]) : 1);
inc *= (start > end ? -1 : 1); // Figure out which direction to increment.
// Loop ending condition depends on relative sizes of start and end
for (var i = start; (start < end ? i <= end : i >= end) ; i += inc)
array.Push(i);
return array;
}
var foo = range(1, -100, 8.5)
for(var i=0;i<foo.length;i++){
document.write(foo[i] + ' is item: ' + (i+1) + ' of ' + foo.length + '<br/>');
}
Sortie de ce qui précède:
1 est article: 1 de 12
-7.5 est le produit: 2 de 12
-16 Est le produit: 3 de 12
-24.5 est l'article: 4 de 12
-33 est article: 5 de 12
-41.5 est l'article: 6 de 12
-50 est article: 7 de 12
-58.5 est l'article: 8 de 12
-67 Est le produit: 9 de 12
-75.5 est l'article: 10 de 12
-84 est article: 11 de 12
-92.5 est l'article: 12 de 12
Cette fonction utilise le tableau arguments
généré automatiquement.
La fonction crée un tableau rempli de valeurs commençant par start
et se terminant par end
avec des incréments de taille increment
, où
range(start, end, increment);
Chaque valeur a une valeur par défaut et le signe de l'incrémentation importe peu, car le sens de l'incrémentation dépend de la taille relative du début et de la fin.
'_'.repeat(5).split('').map((_, i) => i + 1)
donnera [1, 2, 3, 4, 5]
Voici le résumé (exécuté en console):
// setup:
var n = 10000000;
function* rangeIter(a, b) {
for (let i = a; i <= b; ++i) yield i;
}
function range(n) {
let a = []
for (; n--; a[n] = n);
return a;
}
function sequence(max, step = 1) {
return {
[Symbol.iterator]: function* () {
for (let i = 1; i <= max; i += step) yield i
}
}
}
var t0, t1, arr;
// tests
t0 = performance.now();
arr = Array.from({ length: n }, (a, i) => 1)
t1 = performance.now();
console.log("Array.from({ length: n }, (a, i) => 1) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = range(n);
t1 = performance.now();
console.log("range(n) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(rangeIter(0, n));
t1 = performance.now();
console.log("Array.from(rangeIter(0, n)) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...rangeIter(0, n)];
t1 = performance.now();
console.log("[...rangeIter(0, n)] Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(sequence(n));
t1 = performance.now();
console.log("Array.from(sequence(n)) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...sequence(n)];
t1 = performance.now();
console.log("[...sequence(n)] Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array(n).fill(0).map(Number.call, Number);
t1 = performance.now();
console.log("Array(n).fill(0).map(Number.call, Number) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = Array.from(Array(n).keys());
t1 = performance.now();
console.log("Array.from(Array(n).keys()) Took " + (t1 - t0) + " milliseconds.");
t0 = performance.now();
arr = [...Array(n).keys()];
t1 = performance.now();
console.log("[...Array(n).keys()] Took " + (t1 - t0) + " milliseconds.");
Le plus rapide est Array (n) .fill (0) .map (Number.call, Number), le second est [... Array (n) .keys ()]
Mais la méthode '... rangeIter' est assez pratique (peut être en ligne), rapide et plus puissante
Solution ES6 utilisant la récursivité. Différent de toutes les autres solutions
const range = (n, A = []) => (n === 1) ? [n, ...A] : range(n - 1, [n, ...A]);
console.log(range(5));
Le moins de codes que je pourrais produire:
for(foo=[x=100]; x; foo[x-1]=x--);
console.log(foo);
pour obtenir un tableau avec n nombres aléatoires entre min, max (pas unique cependant)
function callItWhatYouWant(n, min, max) {
return Array.apply(null, {length: n}).map(Function.call, function(){return Math.floor(Math.random()*(max-min+1)+min)})
}
Eh bien, question simple mais importante. JS fonctionnel manque définitivement d'une méthode de déploiement générique sous l'objet Array, car il se peut que nous devions créer un tableau d'éléments numériques, non seulement le simple [1,2,3,...,111]
, mais une série résultant d'une fonction, peut ressembler à x => x*2
au lieu de x => x
Actuellement, pour effectuer ce travail, nous devons nous appuyer sur la méthode Array.prototype.map()
. Cependant, pour utiliser Array.prototype.map()
, nous devons connaître la taille du tableau à l’avance. Eh bien quand même… si nous ne connaissons pas la taille, nous pouvons utiliser Array.prototype.reduce()
mais Array.prototype.reduce()
est destiné à réduire le pliage ne se déroulant pas correctement…?
Nous avons donc évidemment besoin d’un outil Array.unfold()
dans JS fonctionnel. C’est quelque chose que nous pouvons simplement nous appliquer nous-mêmes.
Array.unfold = function(p,f,t,s){
var res = [],
runner = v => p(v,res.length-1,res) ? [] : (res.Push(f(v)),runner(t(v)), res);
return runner(s);
};
Arrays.unfold(p,f,t,v)
prend 4 arguments.
p
prend 3 arguments comme le font de nombreux foncteurs de tableaux. La valeur, l'index et le tableau résultant. Il doit retourner une valeur booléenne. Quand il retourne une true
, l'itération récursive s'arrête.f
.Donc, si nous avons l’intention de créer un tableau rempli d’une série comme 1,4,9,16,25 ... n ^ 2, nous pouvons simplement faire comme.
Array.unfold = function(p,f,t,s){
var res = [],
runner = v => p(v,res.length-1,res) ? [] : (res.Push(f(v)),runner(t(v)), res);
return runner(s);
};
var myArr = Array.unfold((_,i) => i >= 9, x => Math.pow(x,2), x => x+1, 1);
console.log(myArr);
Il y a une petite fonction, cela permet d'utiliser une construction comme [1, 2] .range (3, 4) -> [1, 2, 3, 4] et cela fonctionne aussi avec des paramètres négatifs. Prendre plaisir.
Array.prototype.range = function(from, to)
{
var range = (!to)? from : Math.abs(to - from) + 1, increase = from < to;
var tmp = Array.apply(this, {"length": range}).map(function()
{
return (increase)?from++ : from--;
}, Number);
return this.concat(tmp);
};
pour moi c'est un utilitaire plus utile:
/**
* create an array filled with integer numbers from base to length
* @param {number} from
* @param {number} to
* @param {number} increment
* @param {Array} exclude
* @return {Array}
*/
export const count = (from = 0, to = 1, increment = 1, exclude = []) => {
const array = [];
for (let i = from; i <= to; i += increment) !exclude.includes(i) && array.Push(i);
return array;
};
Azle a une fonction utilitaire appelée create_array, qui vous donne un certain nombre d'options:
Créez un tableau de 0 à 5:
az.create_array(0, 5)
[0, 1, 2, 3, 4, 5
Créez un tableau de 1 à 5:
az.create_array(1, 5)
[1, 2, 3, 4, 5]
Créez un tableau de 5 tableaux:
az.create_array(1, 5, ['apples','carrots','oranges'])
[ ["pommes", "carottes", "oranges"], ["pommes", "carottes", "oranges"], ["pommes", "carottes", "oranges" ], ["pommes", "carottes", "oranges"], ["pommes", "carottes", "oranges"] ]
Créez un tableau de 5 objets:
az.create_array(1, 5, {"color" : "orangered"})
[{color: "orangered"}, {color: "orangered"}, {color: "orangered"}, {color: "orangered"}, {color: "orangered "}]
Créez un tableau de 6 nombres aléatoires:
az.create_array(0,5,'random') // default draws from 10
[9, 5, 4, 6, 9, 7]
Créez un tableau de 6 nombres aléatoires tirés de 1000:
az.create_array(0,5,'random', 1000)
[180, 372, 678, 142, 314, 438]
Voici le VIOLON
Comme il y a beaucoup de bonnes réponses, cela pourrait également être une option, vous pouvez également créer une fonction avec le texte ci-dessous et cela fonctionnera pour toute combinaison de nombres.
const start = 10;
const end = 30;
const difference = Math.abs(start-end);
const rangeArray = new Array(difference + 1).fill(undefined).map((val, key) => {
return start > end ? start - key : start + key;
})
Pour les petites gammes, une tranche est Nice. N n'est connu qu'à l'exécution, donc:
[0, 1, 2, 3, 4, 5].slice(0, N+1)
a = Object.keys( [].fill.call({length:7}, '' ) ).map(Number)
a.pop();
console.debug(a)
[0, 1, 2, 3, 4, 5, 6]