javascript algorithms and data structures
La forma más sencilla de crear una matriz de enteros a partir de 1..20 en JavaScript (12)
¿Cuál sería la forma más sencilla de crear esta matriz?
var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
Por ejemplo, un bucle for
:
var x = [];
for (var i=1;i<=20;i++) {
x.push(i);
}
O un ciclo while:
var x = [], i = 1, endInt = 20;
while (i <= endInt) {
x.push(i);
i++;
}
¿Habría otros ejemplos que serían más extravagantes, en otras palabras, menos código? Estoy pensando en cosas como Ruby, donde creo que el código equivalente sería tan simple como 1..20
. No conozco una sintaxis como esa en JavaScript, pero me pregunto si hay formas más cortas de hacer lo mismo.
ACTUALIZACIÓN: No estaba pensando en eliminar puntos y comas o var
para obtener respuestas en la pregunta, pero debo admitir que la pregunta implica eso. Tengo más curiosidad por los algoritmos que por afeitar los bytes. Lo siento si no estaba claro Además, convertirlo en una función es lo suficientemente simple, simplemente abofetee el function range(start, end) { /* guts here */ }
a su alrededor y usted estará allí. La pregunta es si hay nuevos enfoques para las "agallas".
En mi conocimiento, la opción de usar for loop, como mencionaste, es la más estricta.
Es decir,
var x = [];
for (var i=1;i<=20;i++) {
x.push(i);
}
No puedo pensar en una forma con menos personajes que ~ 46:
var a=[];while(a.length<20)a.push(a.length+1);
De acuerdo, podrías hacer una función de eso.
Al leer sus comentarios sobre una función, podría hacer algo como
var range = function (start, end) {
var arr = [];
while (start <= end) {
arr.push(start++)
}
return arr;
};
Entonces el range(1, 20)
devolvería la matriz como se esperaba.
Si buscas afeitar a los personajes de todos modos sin tener en cuenta la legibilidad, esto es lo mejor que puedo hacer:
var x=[],i=0
while(i<20)
x[i]=i+++1
Aunque no mucho mejor que el tuyo.
Editar:
En realidad, esto funciona mejor y reduce un par de personajes:
var x=[],i=0
while(i<20)
x[i]=++i
Editar 2:
Y aquí está mi entrada para una función general de "rango" en la menor cantidad de caracteres:
function range(s,e){var x=[];while(s<e+1)x.push(s++);return x}
Nuevamente, no escriba el código de esta manera. :)
Siempre puedes crear una función ...
function createNumArray(a, b) {
var arr = [],
i = a;
while((arr[arr.length] = i) < b) {i++}
return arr;
}
Lo que le permite escribir un código sucinto más adelante, como ...
var arr = createNumArray(1, 20);
var i = 0;
var x = [];
while (i++ < 20) x.push(i);
Ampliaré el prototipo de Array para que sea más fácil de acceder:
Array.prototype.range = function(start, end) {
if (!this.length) {
while (end >= start) {
this.push(start++);
}
} else {
throw "You can only call ''range'' on an empty array";
}
return this;
};
var array = [].range(1, 20);
Si bien lo anterior es lo más cercano que puedo pensar con respecto al azúcar sintáctico que está buscando, es posible que desee probar CoffeeScript .
Es compatible con la notación que está buscando.
CoffeeScript:
test = [1..20]
alert test
Renders a JavaScript:
var test;
test = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
alert(test);
Puede probar ejemplos en vivo en su sitio y ver la conversión que hace mientras escribe.
Simplemente haga clic en el enlace TRY COFFEESCRIPT en la parte superior y obtendrá una consola donde podrá probar algún código.
while-- es el camino a seguir
var a=[],b=10;while(b--)a[b]=b+1
devuelve [1,2,3,4,5,6,7,8,9,10]
explicado con inicio y duración
var array=[],length=20,start=5;while(length--)array[length]=length+start
regresa [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
quiere rango?
explicado con inicio y final
var array=[],end=30,start=25,a=end-start+1;while(a--)array[a]=end--
regresa [25, 26, 27, 28, 29, 30]
para --
for(var a=[],b=20;b>0;b--,a[b]=b+1)
para ++
for(var a=[],b=0;b<20;b++,a[b]=b+1)
¿POR QUÉ es este camino a seguir?
1.while - prolly es el ciclo más rápido;
La configuración 2.direct es más rápida que push & concat;
3. [] también es más rápido que la nueva matriz (10);
4. no es un código mucho más largo que todos los demás
técnicas de ahorro de bytes
1.utilice los argumentos como un placholder para las variables de función. 2.no use los nuevos Array (), push (), concat () si no es necesario 3.place "() {} ;," solo cuando sea necesario. 4.utiliza a, b, c, d ... en funciones cortas. así que si quieres una función para esto
con inicio, final (rango)
function range(a,b,c,d){d=[];c=b-a+1;while(c--)d[c]=b--;return d}
entonces ahora el rango (3,7) devuelve [3,4,5,6,7]
Ahorre bytes de muchas formas aquí y esta función también es muy rápida ya que no usa concat, push, new Array y está hecha con un tiempo.
Puede hacer esto con un ciclo while donde la inserción ocurre dentro de la condición. Array.push devuelve la longitud de la matriz, que resulta ser la misma que el valor en este caso. Entonces, puedes hacer lo siguiente:
x = []; //normally would use var here
i = 1; //normally would use var here
while(x.push(i++)<20){}
//at this point, x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Versión condensada (31 caracteres)
x=[];i=1;while(x.push(i++)<20);
Se puede hacer con las características de ES6, actualmente solo es compatible con Firefox. Encontré una tabla de compatibilidad aquí: http://kangax.github.io/compat-table/es6/
Array.from(new Array(20), (x,i) => i+1)
Si quieres tener otro rango, entonces creo que podrías hacer
Array.from(new Array(5), (x,i) => i+5)
Que sería entonces [5,6,7,8,9]
Usando ES6
numArr = Array(5).fill(0).reduce(arr=>{ arr.push(arr.length); return arr },[])
Supongo que esta es la forma más corta:
var i=0, arr = [];
while (i++<20){
arr.push(i);
}
o asociándose al código ''perverso'' en la respuesta de EndangeredMassa :
var i,arr; while (i=i||1, (arr=arr||[]).push(i++)<20){}
Después de pensarlo un poco, esta es la implementación más corta de la función de range(N)
estándar range(N)
en JavaScript que podría surgir:
function range1(i){return i?range1(i-1).concat(i):[]}
Nota : No use esto en producción; es O (N ^ 2)
Contraste con la respuesta actual mejor votado:
function range1(i){var x=[];var i=1;while(x.push(i++)<i){};return x}
Ejemplo:
> range1(5)
[1, 2, 3, 4, 5]
Esto es como el poster child para recursión, aunque esperaba que fuera más largo hasta que pensé en ternary-if-statement, que lo reduce a 42 caracteres necesarios.
Tenga en cuenta que la función de range
"estándar" que devuelve [inicio, fin) puede escribirse haciendo .concat(i-1)
.
Actualización: Ooh, descubrí una versión increíblemente corta con fea sintaxis imperativa al abusar de bucles, orden inverso, el hecho de que las asignaciones devuelvan un valor: for(y=[],i=20;y[--i]=i;){}
consta de solo 25 caracteres (aunque deseará var y
que se puede insertar en un ciclo for, y +1 si no desea 0 ... 19). Si bien no es más corto si necesita definir una función, es más corto que i?r(i-1).concat(i):[]
si no necesita realizar una función.
Método favorito
Actualización Sep13,2015:
Acabo de presentar este nuevo método que funciona con navegadores compatibles con el estándar ES6:
> Array(5).fill().map((x,i)=>i)
[0, 1, 2, 3, 4]
También esto:
> Array.from(Array(5),(x,i)=>i)
[0, 1, 2, 3, 4]
Se agregaron algunos casos de análisis de rendimiento: parece que todo, además de un bucle for-for estándar, es 10 veces más lento, al menos en V8. https://jsperf.com/array-range-in-javascript (Por supuesto, nada de esto importa si estás programando en un estilo funcional de todos modos y golpearía cada elemento con una llamada de función de todos modos).