Foros del Web » Programando para Internet » Javascript »

[APORTE] Función range() equivalente a su similar de PHP

Estas en el tema de [APORTE] Función range() equivalente a su similar de PHP en el foro de Javascript en Foros del Web. Hola amigos del foro, en esta ocasión, quiero compartir con ustedes esta pequeña y mejorable función (porque creo que puede ser más eficiente) para generar ...
  #1 (permalink)  
Antiguo 29/05/2014, 18:35
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
[APORTE] Función range() equivalente a su similar de PHP

Hola amigos del foro, en esta ocasión, quiero compartir con ustedes esta pequeña y mejorable función (porque creo que puede ser más eficiente) para generar un array mediante un rango indicado, ya sea este de números o letras.

Código Javascript:
Ver original
  1. var range = function(array, start, end, step){
  2.         array.push(start);
  3.         start = typeof start === "string" ?
  4.                 String.fromCharCode(start.charCodeAt(0) + (step || 1)) :
  5.                 start += step || 1;
  6.         return start <= end ? range(array, start, end, step) : array;
  7.     };
  8.  
  9. console.log(range([], 1, 10));
  10. console.log(range([], "a", "z"));
  11. console.log(range([], "A", "Z"));
  12. console.log(range([], 1, 10, 2));

Los resultados para lo anterior son los siguientes:

Código HTML:
Ver original
  1. 1,2,3,4,5,6,7,8,9,10
  2. a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
  3. A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
  4. 1,3,5,7,9

Cualquier duda, sugerencia o crítica constructiva, será bienvenida.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 29/05/2014 a las 23:16 Razón: Mejora
  #2 (permalink)  
Antiguo 30/05/2014, 03:01
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

Muy bien!! Gracias

Deberias asegurarte que si start o end son string solo sean de un caracter.

O modificar la función para que sea capaz de solucionar esto

console.log(range([], "ab", "yz"));

ab,ac,ad,....,ya,.....,yy,yz

tambien deberías asegurarte que start < end o que en ese caso los steps sean negativos.

Que start, end sean del mismo tipo.

Uff queria ser constructivo y me estan saliendo demasiadas cosas.
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 30/05/2014 a las 03:07
  #3 (permalink)  
Antiguo 30/05/2014, 08:21
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años
Puntos: 292
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

Buena idea...... y como mencionas a PHP me hace acordar a mi implementacion de Range como clase para PHP pues tambien es iterable como tu version en JS:

Código Javascript:
Ver original
  1. range([], 1, 10)[5]
__________________
Salu2!
  #4 (permalink)  
Antiguo 30/05/2014, 13:23
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

Gracias quimfv por las observaciones, de hecho esta función es mejorable. Ayer, luego de publicarla, me puse a pensar en las mejoras que se le pueden hacer, pero como estoy avanzando con un proyecto para un cliente, no las pude implementar y de hecho que estaba el tema de que start sea menor que end. ¿De verdad crees que no estás siendo constructivo? Pues opino todo lo contrario.

Hey, Italico76, no había visto tu clase en PHP, está excelente.

Bueno, sin más rodeos, aquí está la versión 2.0 de la función range():

Código Javascript:
Ver original
  1. var range = function(array, start, end, step){
  2.         if (typeof start === typeof end){
  3.             array.push(typeof start === "string" ? start[0] : start);
  4.             step = start > end ?
  5.                    !isNaN(step) && isFinite(step) && step < 0 ? step : -step || -1 :
  6.                    !isNaN(step) && isFinite(step) ? step : 1;
  7.             start = typeof start === "string" ?
  8.                     String.fromCharCode(start.charCodeAt(0) + step) :
  9.                     start += step;
  10.             return (step > 0 && start <= end) || (step < 0 && start >= end) ?
  11.                     range(array, start, end, step) : array;
  12.         }
  13.         return false;
  14.     };
  15.  
  16. console.log(range([], "a", "z"));
  17. console.log(range([], "ab", "yz"));
  18. console.log(range([], 1, 10));
  19. console.log(range([], 10, 1));
  20. console.log(range([], 10, 1, 1.5)); //Toma la parte entera
  21. console.log(range([], 10, 1, "4")); //Toma el 4 como valor numérico, ignorando su tipo
  22. console.log(range([], 10, 1, "a")); //Toma el 1 como valor por defecto, ignorando la "a"
  23. console.log(range([], 10, 1, -2));
  24. console.log(range([], 10, "1"));

Esto imprime lo siguiente:

Código HTML:
Ver original
  1. a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
  2. a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y
  3. 1,2,3,4,5,6,7,8,9,10
  4. 10,9,8,7,6,5,4,3,2,1
  5. 10,9,8,7,6,5,4,3,2,1
  6. 10,6,2
  7. 10,9,8,7,6,5,4,3,2,1
  8. 10,8,6,4,2
  9. false

Mejoras implementadas:
  • Opera solo con límites del mismo tipo.
  • En caso de ser letras, solo toma a la primera.
  • Si start es mayor que end, los pasos se dan hacia atrás, creándose una lista en orden descendente.
  • El valor de step tiene que ser numérico (no precisamente el tipo), de lo contrario, se incrementa/decrementa el valor de los pasos de 1 en 1.

Al igual que con la función range() de PHP, si los límites fueran ab hasta yz, solo se toma el primer caracter, tal y como lo pueden comprobar en este ejemplo. Como ahora la función permite la creación de una lista de valores en orden descendente, da igual si step es positivo o negativo.

Cuando termine con mis labores, veré qué más mejoras se pueden hacer, pero si tienen otras, solo díganmelas y las implemento.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 30/05/2014 a las 14:53 Razón: Mejora
  #5 (permalink)  
Antiguo 30/05/2014, 15:58
Avatar de jp91  
Fecha de Ingreso: mayo-2014
Mensajes: 94
Antigüedad: 9 años, 11 meses
Puntos: 11
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

No entiendo para que pasar el array como parametro.pero bueno.

Código Javascript:
Ver original
  1. function range(comienzo,fin, paso) {
  2.   //  discusion : http://phpjs.org/functions/range/
  3.   // originalmente hecho por : Waldo Malqui Silva
  4.  
  5.  
  6.   var resultado = [];
  7.   var valorIni, valorFinal, suma;
  8.   var aux = paso || 1;
  9.   var letras = false;
  10.  
  11.   if (!isNaN(comienzo) && !isNaN(fin)) {
  12.     valorIni = comienzo;
  13.     valorFinal = fin;
  14.   } else if (isNaN(comienzo) && isNaN(fin)) {
  15.     letras = true;
  16.     valorIni = comienzo.charCodeAt(0);
  17.     valorFinal = fin.charCodeAt(0);
  18.   } else {
  19.     valorIni = (isNaN(comienzo) ? 0 : comienzo);
  20.     valorFinal = (isNaN(fin) ? 0 : fin);
  21.   }
  22.  
  23.   suma = ((valorIni > valorFinal) ? false : true);
  24.   if (suma) {
  25.     while (valorIni <= valorFinal) {
  26.       resultado.push(((letras) ? String.fromCharCode(valorIni) : valorIni));
  27.       valorIni += aux;
  28.     }
  29.   } else {
  30.     while (valorIni >= valorFinal) {
  31.       resultado.push(((letras) ? String.fromCharCode(valorIni) : valorIni));
  32.       valorIni -= aux;
  33.     }
  34.   }
  35.  
  36.   return resultado;
  37. };
__________________
OOoo Como hacer ooOO
juegos con Html5.
  #6 (permalink)  
Antiguo 30/05/2014, 16:10
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

Paso un array porque la función es recursiva, no hago uso de bucles como en tu ejemplo. Si creara un array en la función, siempre se reemplazaría por otro, a menos que pueda declarárselo de tipo static como en PHP, aunque no estoy seguro de que eso se pueda. Por cierto, es más eficiente hacer esto:

Código Javascript:
Ver original
  1. var a, b, c;

Que esto:

Código Javascript:
Ver original
  1. var a;
  2. var b;
  3. var c;

Y ten en cuenta que con !isNaN(comienzo) no basta para comprobar que se trata de un valor numérico, pues si haces !isNaN(""), también obtendrás true por respuesta.

Saludos

Edito: Tengo algunas observaciones sobre tu función. Si paso es una cadena, siempre inserta el primer valor de la secuencia al array, pero ahí se detiene, incluso si la cadena es un número como "4". Por otro lado, si paso es negativo, no se respetan los límites, probé con un rango de 10 a 1 con paso -2 y el último número de la lista fue el 114467.

Bueno, al menos estamos aprendiendo todos aquí.
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 30/05/2014 a las 16:22 Razón: Observaciones
  #7 (permalink)  
Antiguo 30/05/2014, 16:26
Avatar de jp91  
Fecha de Ingreso: mayo-2014
Mensajes: 94
Antigüedad: 9 años, 11 meses
Puntos: 11
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

pasar el array no se me siento raro pero entre gustos, jejejej no esa funcion no la hice yo como puedes ver hay esta quien la hizo y la discusion con sus diferentes adaptaciones.

claro si nos dedicamos a mejorarla psssss..., y tanto como static hay es la famosas variables estaticas en el prototype de la clase.
__________________
OOoo Como hacer ooOO
juegos con Html5.
  #8 (permalink)  
Antiguo 30/05/2014, 16:44
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

Para crear métodos estáticos, no es necesario el uso de prototype, basta con hacer uso de la Dot Notation o la Bracket Notation para crear métodos estáticos en la función, pues al fin y al cabo, en JS todos son objetos.

Lo malo está en que al ser estático, al llamar a la función para generar otro array, se añade al que previamente se creó. Veré si puedo adaptar esto.

Edito: Sí se pudo.

Código Javascript:
Ver original
  1. var range = function(start, end, step){
  2.         range.array = range.array || [];
  3.         if (typeof start === typeof end){
  4.             range.array.push(typeof start === "string" ? start[0] : start);
  5.             step = start > end ?
  6.                    !isNaN(step) && isFinite(step) && step < 0 ? step : -step || -1 :
  7.                    !isNaN(step) && isFinite(step) ? step : 1;
  8.             start = typeof start === "string" ?
  9.                     String.fromCharCode(start.charCodeAt(0) + step) :
  10.                     start += step;
  11.             return (step > 0 && start <= end) || (step < 0 && start >= end) ?
  12.                     range(start, end, step) : (function(){
  13.                         var aux = range.array;
  14.                         range.array = [];
  15.                         return aux;
  16.                     })();
  17.         }
  18.         return false;
  19.     };
  20.  
  21. console.log(range(1, 10)); //1,2,3,4,5,6,7,8,9,10
  22. console.log(range("a", "z")); //a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #9 (permalink)  
Antiguo 30/05/2014, 16:59
Avatar de jp91  
Fecha de Ingreso: mayo-2014
Mensajes: 94
Antigüedad: 9 años, 11 meses
Puntos: 11
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

jejejej si claro que todo es objeto bueno "casi" solo te decia un ejemplo general, ya se me hacia raro eso de <al llamar a la función para generar otro array, se añade al que previamente se creó> pero ya veo compruebas el array.

Si esa es la idea compartir y aprender un poco mas.:)
__________________
OOoo Como hacer ooOO
juegos con Html5.
  #10 (permalink)  
Antiguo 30/05/2014, 17:03
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

Claro, con esto de que son llamadas recursivas, al primer llamado no existirá y es ahí en donde se crea para que no sea el usuario el que lo cree, ya luego de ser creado, simplemente se le añaden los valores y antes de entregarse el resultado, hago una copia del array la cual será enviada y al original lo dejo vacío para poder utilizarlo en el futuro y crear listas con otros elementos. Y sí, en JS casi todo son objetos, me olvidé del casi que casi siempre pongo.

Gracias por tu participación, jp91, así es como debemos de trabajar en la comunidad.
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #11 (permalink)  
Antiguo 30/05/2014, 17:26
Avatar de jp91  
Fecha de Ingreso: mayo-2014
Mensajes: 94
Antigüedad: 9 años, 11 meses
Puntos: 11
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

jjeje Es interesante ver lo que pasaria aqui haciendo un calculo mental si colocamos como inicio "a" en minusculas y "Z" en mayusculas me imagino que se volvera loco.
__________________
OOoo Como hacer ooOO
juegos con Html5.
  #12 (permalink)  
Antiguo 30/05/2014, 17:31
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

Sucede lo mismo que en PHP.

Justo estoy trabajando en algunas mejoras, también tomaré eso en cuenta.
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #13 (permalink)  
Antiguo 30/05/2014, 18:16
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: [APORTE] Función range() equivalente a su similar de PHP

Bueno, luego de haber pensado y probado algunas mejoras, aquí está la versión 3.0 de la función range():

Código Javascript:
Ver original
  1. var range = function(start, end, step){
  2.         range.array = range.array || [];
  3.        
  4.         if (typeof start !== typeof end){
  5.             start = !isNaN(Number(start)) && isFinite(Number(start)) ? Number(start) : 0;
  6.             end = !isNaN(Number(end)) && isFinite(Number(end)) ? Number(end) : 0;
  7.         }
  8.  
  9.         if (typeof start === "string")
  10.             start = !isNaN(Number(start)) && isFinite(Number(start)) ? Number(start) : start[0].toLowerCase();
  11.         if (typeof end === "string")
  12.             end = !isNaN(Number(end)) && isFinite(Number(end)) ? Number(end) : end[0].toLowerCase();
  13.  
  14.         range.array.push(start);
  15.  
  16.         if (!isNaN(step) && isFinite(step))
  17.             step = start > end ?
  18.                    Number(step > 0 ? -step || -1 : step || -1) :
  19.                    Number(step < 0 ? -step || 1 : step || 1);
  20.         else
  21.             step = start > end ? -1 : 1;
  22.  
  23.         start = typeof start === "string" ?
  24.                 String.fromCharCode(start.charCodeAt(0) + step) :
  25.                 start += step;
  26.  
  27.         return (step > 0 && start <= end) || (step < 0 && start >= end) ?
  28.                 range(start, end, step) : (function(){
  29.                     var aux = range.array;
  30.                     range.array = [];
  31.                     return aux;
  32.                 })();
  33.     };
  34.  
  35. console.log(range("z", "A"));
  36. console.log(range("Z", "a"));
  37. console.log(range("z", "a"));
  38. console.log(range("a", "Z"));
  39. console.log(range("A", "z"));
  40. console.log(range("a", "z"));
  41. console.log(range("ab", "yz"));
  42. console.log(range(1, 10));
  43. console.log(range(10, 1));
  44. console.log(range(10, 1, 1.5));
  45. console.log(range(1, 10, "-4"));
  46. console.log(range(10, 1, "-4"));
  47. console.log(range(1, 10, "4"));
  48. console.log(range(10, 1, "4"));
  49. console.log(range(10, 1, "a"));
  50. console.log(range(10, 1, -2));
  51. console.log(range(1, 10, 2));
  52. console.log(range("1", 10));
  53. console.log(range(10, "1"));
  54. console.log(range(10, "a"));
  55. console.log(range(1, 10, -2));
  56. console.log(range("a", 10));
  57. console.log(range("1", "10"));
  58. console.log(range("10", "1"));

Los resultados son los siguientes:

Código HTML:
Ver original
  1. z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a
  2. z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a
  3. z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a
  4. a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
  5. a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
  6. a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
  7. a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y
  8. 1,2,3,4,5,6,7,8,9,10
  9. 10,9,8,7,6,5,4,3,2,1
  10. 10,8.5,7,5.5,4,2.5,1
  11. 1,5,9
  12. 10,6,2
  13. 10,9,8,7,6,5,4,3,2,1
  14. 10,8,6,4,2
  15. 1,3,5,7,9
  16. 1,2,3,4,5,6,7,8,9,10
  17. 10,9,8,7,6,5,4,3,2,1
  18. 10,9,8,7,6,5,4,3,2,1,0
  19. 1,3,5,7,9
  20. 0,1,2,3,4,5,6,7,8,9,10
  21. 1,2,3,4,5,6,7,8,9,10
  22. 10,9,8,7,6,5,4,3,2,1

Mejoras implementadas:
  • Si los tipos de dato de los límites son diferentes, la función toma sus valores numéricos en caso de tenerlos, dígase "4", "100", mas no "a" o "b", caso contrario, se asigna 0 ya sea a start y/o a end.
  • En caso de tener letras como límites y de estar uno de ellos en mayúscula y el otro en minúscula, siempre serán convertidos a minúsculas y se operarán como tales, obteniendo así el valor Unicode correspondiente a la letra en cuestión en minúscula.
  • Siempre toma el valor numérico de step, para así poder dar pasos de, por ejemplo, "-4" o "4", los cuales serán tomados como -4 y 4, respectivamente.
  • Si los límites son cadenas pero con valor numérico, dígase "1" y "10", se toma el valor numérico de ambos.

Cualquier otro aporte o sugerencia, será bienvenido.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 31/05/2014 a las 17:47 Razón: Ejemplos y mejoras

Etiquetas: arrays, range
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:42.