repetir rango para numeros numero generar entre entero codigo aleatorios aleatorio javascript arrays ecmascript-6

javascript - para - ¿Cómo generar un rango de números de 0 an en ES2015 solamente?



random entre 0 y 10 javascript (12)

Aquí hay otra variación que no usa Array .

let range = (n, l=[], delta=1) => { if (n < 0) { return l } else { l.unshift(n) return range(n - delta, l) } }

Siempre he encontrado la función de range que falta en JavaScript, ya que está disponible en Python y otros. ¿Hay alguna forma concisa de generar un rango de números en ES2015?

EDITAR: MI pregunta es diferente del duplicado mencionado ya que es específica de ES2015 y no de ECMASCRIPT-5. También necesito que el rango comience desde 0 y no un número de inicio específico (aunque sería bueno si eso está allí)


Con Delta

Para javascript

Array.from(Array(10).keys()).map(i => 4 + i * 2); //=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22] [...Array(10).keys()].map(i => 4 + i * -2); //=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14] Array(10).fill(0).map((v, i) => 4 + i * 2); //=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22] Array(10).fill().map((v, i) => 4 + i * -2); //=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14] [...Array(10)].map((v, i) => 4 + i * 2); //=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22] const range = (from, to, step) => Array(~~((to - from) / step) + 1) // ''~~'' is Alternative for Math.floor() .fill().map((v, i) => from + i * step); range(0, 9, 2); //=> [0, 2, 4, 6, 8] Array.range = (from, to, step) => Array.from({ length: ~~((to - from) / step) + 1 }, (v, k) => from + k * step ); Array.range = (from, to, step) => [...Array(~~((to - from) / step) + 1)].map( (v, k) => from + k * step ) Array.range(2, 10, 2); //=> [2, 4, 6, 8, 10] Array.range(0, 10, 1); //=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Array.range(2, 10, -1); //=> [] Array.range(3, 0, -1); //=> [3, 2, 1, 0] class Range { constructor(total = 0, step = 1, from = 0) { this[Symbol.iterator] = function*() { for (let i = 0; i < total; yield from + i++ * step) {} }; } } [...new Range(5)]; // Five Elements //=> [0, 1, 2, 3, 4] [...new Range(5, 2)]; // Five Elements With Step 2 //=> [0, 2, 4, 6, 8] [...new Range(5, -2, 10)]; // Five Elements With Step -2 From 10 //=>[10, 8, 6, 4, 2] [...new Range(5, -2, -10)]; // Five Elements With Step -2 From -10 //=> [-10, -12, -14, -16, -18] // Also works with for..of loop for (i of new Range(5, -2, 10)) console.log(i); // 10 8 6 4 2 // Or const Range = function*(total = 0, step = 1, from = 0){ for (let i = 0; i < total; yield from + i++ * step) {} }; Array.from(Range(5, -2, -10)); //=> [-10, -12, -14, -16, -18] [...Range(5, -2, -10)]; // Five Elements With Step -2 From -10 //=> [-10, -12, -14, -16, -18] // Also works with for..of loop for (i of Range(5, -2, 10)) console.log(i); // 10 8 6 4 2 class Range2 { constructor(to = 0, step = 1, from = 0) { this[Symbol.iterator] = function*() { let i = 0, length = ~~((to - from) / step) + 1; while (i < length) yield from + i++ * step; }; } } [...new Range2(5)]; // First 5 Whole Numbers //=> [0, 1, 2, 3, 4, 5] [...new Range2(5, 2)]; // From 0 to 5 with step 2 //=> [0, 2, 4] [...new Range2(5, -2, 10)]; // From 10 to 5 with step -2 //=> [10, 8, 6] // Or const Range2 = function*(to = 0, step = 1, from = 0) { let i = 0, length = ~~((to - from) / step) + 1; while (i < length) yield from + i++ * step; }; [...Range2(5, -2, 10)]; // From 10 to 5 with step -2 //=> [10, 8, 6] let even4to10 = Range2(10, 2, 8); even4to10.next().value //=> 8 even4to10.next().value //=> 10 even4to10.next().value //=> undefined

Para mecanografiado

interface _Iterable extends Iterable < {} > { length: number; } class _Array < T > extends Array < T > { static range(from: number, to: number, step: number): number[] { return Array.from( ( < _Iterable > { length: Math.floor((to - from) / step) + 1 }), (v, k) => from + k * step ); } } _Array.range(0, 9, 1); //=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

Actualizar

class _Array<T> extends Array<T> { static range(from: number, to: number, step: number): number[] { return [...Array(~~((to - from) / step) + 1)].map( (v, k) => from + k * step ); } } _Array.range(0, 9, 1);

Editar

class _Array<T> extends Array<T> { static range(from: number, to: number, step: number): number[] { return Array.from(Array(~~((to - from) / step) + 1)).map( (v, k) => from + k * step ); } } _Array.range(0, 9, 1);


Entonces, en este caso, sería bueno si el objeto Number se comportara como un objeto Array con el operador spread.

Por ejemplo, el objeto Array utilizado con el operador de propagación:

let foo = [0,1,2,3]; console.log(...foo) // returns 0 1 2 3

Funciona así porque el objeto Array tiene un iterador incorporado.
En nuestro caso, necesitamos un objeto Number para tener una funcionalidad similar:

[...3] //should return [0,1,2,3]

Para hacer eso, simplemente podemos crear un iterador de números para ese propósito.

Number.prototype[Symbol.iterator] = function *() { for(let i = 0; i <= this; i++) yield i; }

Ahora es posible crear rangos de 0 a N con el operador de propagación.

[... N] // ahora devuelve 0 ... N array

http://jsfiddle.net/01e4xdv5/4/

Aclamaciones.


Esta función devolverá una secuencia entera.

const integerRange = (start, end, n = start, arr = []) => (n === end) ? [...arr, n] : integerRange(start, end, start < end ? n + 1 : n - 1, [...arr, n]); $> intSequence(1, 1) <- Array [ 1 ] $> intSequence(1, 3) <- Array(3) [ 1, 2, 3 ] $> intSequence(3, -3) <- Array(7) [ 3, 2, 1, 0, -1, -2, -3 ]


Muchas de estas soluciones se basan en la creación de instancias de objetos Array reales, que pueden hacer el trabajo para muchos casos, pero no pueden admitir casos como el range(Infinity) . Podría usar un generador simple para evitar estos problemas y admitir secuencias infinitas:

function* range( start, end, step = 1 ){ if( end === undefined ) [end, start] = [start, 0]; for( let n = start; n < end; n += step ) yield n; }

Ejemplos:

Array.from(range(10)); // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] Array.from(range(10, 20)); // [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ] i = range(10, Infinity); i.next(); // { value: 10, done: false } i.next(); // { value: 11, done: false } i.next(); // { value: 12, done: false } i.next(); // { value: 13, done: false } i.next(); // { value: 14, done: false }


Para apoyar el delta

const range = (start, end, delta) => { return Array.from( {length: (end - start) / delta}, (v, k) => (k * delta) + start ) };


Puede usar el operador de propagación en las teclas de una matriz recién creada.

[...Array(n).keys()]

o

Array.from(Array(n).keys())

La sintaxis Array.from() es necesaria si se trabaja con TypeScript


Puede usar una función de generador, que crea el rango de manera perezosa solo cuando es necesario:

function* range(x, y) { while (true) { if (x <= y) yield x++; else return null; } } const infiniteRange = x => range(x, Infinity); console.log( Array.from(range(1, 10)) // [1,2,3,4,5,6,7,8,9,10] ); console.log( infiniteRange(1000000).next() );

Puede usar una función de generador de orden superior para mapear sobre el generador de range :

function* range(x, y) { while (true) { if (x <= y) yield x++; else return null; } } const genMap = f => gx => function* (...args) { for (const x of gx(...args)) yield f(x); }; const dbl = n => n * 2; console.log( Array.from( genMap(dbl) (range) (1, 10)) // [2,4,6,8,10,12,14,16,18,20] );

Si no tiene miedo, incluso puede generalizar el enfoque del generador para abordar un rango mucho más amplio (juego de palabras):

const rangeBy = (p, f) => function* rangeBy(x) { while (true) { if (p(x)) { yield x; x = f(x); } else return null; } }; const lte = y => x => x <= y; const inc = n => n + 1; const dbl = n => n * 2; console.log( Array.from(rangeBy(lte(10), inc) (1)) // [1,2,3,4,5,6,7,8,9,10] ); console.log( Array.from(rangeBy(lte(256), dbl) (2)) // [2,4,8,16,32,64,128,256] );

Tenga en cuenta que los generadores / iteradores tienen un estado inherente, es decir, hay un cambio de estado implícito con cada invocación de next . El estado es una bendición mixta.


También encontré una forma más intuitiva usando Array.from :

const range = n => Array.from({length: n}, (value, key) => key)

Ahora esta función de range devolverá todos los números a partir de 0 a n-1

Una versión modificada del rango para admitir start y end es:

const range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);

EDITAR Como lo sugiere @ marco6, puede poner esto como un método estático si se adapta a su caso de uso

Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);

y úsalo como

Array.range(3, 9)


También puede hacerlo con un forro único con soporte de pasos como este:

((from, to, step) => ((add, arr, v) => add(arr, v, add))((arr, v, add) => v < to ? add(arr.concat([v]), v + step, add) : arr, [], from))(0, 10, 1)

El resultado es [0, 1, 2, 3, 4, 5, 6 ,7 ,8 ,9] .


Para los números del 0 al 5

[...Array(5).keys()]; => [0, 1, 2, 3, 4]


const keys = Array(n).keys(); [...Array.from(keys)].forEach(callback);

en mecanografiado