Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] Reemplazar última coma por " y"

Estas en el tema de Reemplazar última coma por " y" en el foro de PHP en Foros del Web. Hola, Tengo un script que genera una lista dinámicamente (ejemplo: azucar, pan, leche, ajo, cebolla, sal, manzana, café) lo que quiero es hacer tomar esta ...
  #1 (permalink)  
Antiguo 01/05/2014, 10:38
 
Fecha de Ingreso: abril-2014
Mensajes: 72
Antigüedad: 10 años, 7 meses
Puntos: 5
Reemplazar última coma por " y"

Hola,

Tengo un script que genera una lista dinámicamente (ejemplo: azucar, pan, leche, ajo, cebolla, sal, manzana, café) lo que quiero es hacer tomar esta lista y reemplazar la última coma (,) por " y" (de manera que en nuestro ejemplo quedaría así: azucar, pan, leche, ajo, cebolla, sal, manzana y café).

La lista no siempre se genera con las mismas palabras ni tiene siempre la misma cantidad de elementos.

Desde ya, las gracias.
  #2 (permalink)  
Antiguo 01/05/2014, 12:59
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

Muéstranos la manera en como generas la lista, probablemente en ese mismo bloque se pueda añadir la solución.

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
  #3 (permalink)  
Antiguo 01/05/2014, 13:10
 
Fecha de Ingreso: abril-2014
Mensajes: 72
Antigüedad: 10 años, 7 meses
Puntos: 5
Respuesta: Reemplazar última coma por " y"

Es trayendo un montón de datos de MySQL y concatenando, pero para simplificarlo digamos que es así:

Código PHP:
Ver original
  1. <?php
  2.  
  3.     $array = array("pan", "azucar", "leche");
  4.     $arrayNum = count($array);
  5.     $i = 0;
  6.     $lista = '';
  7.  
  8.     while($i<$arrayNum){
  9.  
  10.         $lista.=$array[$i];
  11.         $lista.=', ';
  12.         $i++;
  13.  
  14.     }
  15.  
  16.     $lista = substr($lista, 0, -2);
  17.  
  18.     echo $lista;
  19.  
  20. ?>
  #4 (permalink)  
Antiguo 01/05/2014, 13:18
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

Código PHP:
Ver original
  1. <?php
  2.  
  3.     $array = array("pan", "azucar", "leche");
  4.    
  5.     $salida = null;
  6.     for ($i=0;$i<count($array)-1;$i++)
  7.         $salida .= $array[$i].' ,';
  8.        
  9.     $salida .= $array[$i]; 
  10.    
  11.        
  12.     echo $salida;
__________________
Salu2!
  #5 (permalink)  
Antiguo 01/05/2014, 13:20
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

En cada iteración, verifica que el valor del contador sea igual al total de elementos del array menos uno, es decir, la última ubicación del mismo. De ser así, colocas " y ", seguido del elemento, caso contrario, va la coma y el elemento.

Código PHP:
Ver original
  1. $array = array("pan", "azucar", "leche");
  2. $arrayNum = count($array);
  3. $i = -1;
  4. $lista = '';
  5.  
  6. while(++$i < $arrayNum)
  7.     $lista .= strlen($lista) ? $i == $arrayNum - 1 ? ' y ' . $array[$i] : ', ' . $array[$i] : $array[$i];
  8.  
  9. echo $lista;

El resultado de esto es lo siguiente:

Código HTML:
Ver original
  1. pan, azucar y leche

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
  #6 (permalink)  
Antiguo 01/05/2014, 13:24
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

Sin duda lo mas simple seria...

Código PHP:
Ver original
  1. <?php
  2.    
  3.     echo implode(',',array("pan", "azucar", "leche"));
__________________
Salu2!
  #7 (permalink)  
Antiguo 01/05/2014, 13:27
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

Italico76, ¿Has leído el título y descripción del tema?
__________________
«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
  #8 (permalink)  
Antiguo 01/05/2014, 13:36
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

Cita:
Iniciado por Alexis88 Ver Mensaje
Italico76, ¿Has leído el título y descripción del tema?
No

Ahora si

Código PHP:
<?php
 
    $array 
= array("pan""azucar""leche""otros");
        
    function 
separar(&$arr)
    {
        
$cant count($arr);    
    
        if (
$cant==0)  return null;        
        
$salida null;
        
        if (
$cant>1)
        {
            for (
$i=0;$i<$cant-2;$i++)
                
$salida .= $arr[$i].' ,';
        
            return 
$salida.$arr[$cant-2].' y '.$arr[$cant-1];  
            
        }else
            return 
$arr[0];      
    
    }
    
    echo 
separar($array);

@Alexis88 : me gusto lo compacta de tu solucion lastima que es ineficiente en CPU .... si te fijas estas haciendo demasiadas preguntas por iteracion.... no hay nada que preguntar

Simula eso con 100.000 elementos y veras que tu solucion es bastante mas lenta
__________________
Salu2!
  #9 (permalink)  
Antiguo 01/05/2014, 13:41
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

Aún más sencillo de como lo había planteado:

Código PHP:
Ver original
  1. $array = array("uno", "dos", "tres");
  2. $string = implode(", ", $array);
  3. echo substr_replace ($string, " y ", strrpos($string, ","), 2);

DEMO

Con esto, evitamos el uso de bucles y el script se vuelve más eficiente.

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
  #10 (permalink)  
Antiguo 01/05/2014, 13:43
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

Cita:
Iniciado por Alexis88 Ver Mensaje
Aún más sencillo de como lo había planteado:

Código PHP:
Ver original
  1. $array = array("uno", "dos", "tres");
  2. $string = implode(", ", $array);
  3. echo substr_replace ($string, " y ", strrpos($string, ","), 2);

DEMO

Con esto, evitamos el uso de bucles y el script se vuelve más eficiente.

Saludos
Ya habria que ver la implementacion de implode() y substr_replace() pero me juego a que si consume mas tiempo porque estas recorriendo el arreglo DOS VECES!!! una vez con cada funcion
__________________
Salu2!
  #11 (permalink)  
Antiguo 01/05/2014, 13:44
 
Fecha de Ingreso: abril-2014
Mensajes: 72
Antigüedad: 10 años, 7 meses
Puntos: 5
Respuesta: Reemplazar última coma por " y"

JAAJAJAJAJAJAJA

Gracias a ambos, creo que con lo que han dicho puedo trabajar.
  #12 (permalink)  
Antiguo 01/05/2014, 13:46
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

Cita:
Iniciado por zyxer Ver Mensaje
JAAJAJAJAJAJAJA

Gracias a ambos, creo que con lo que han dicho puedo trabajar.
Nos alegramos
__________________
Salu2!
  #13 (permalink)  
Antiguo 01/05/2014, 14:11
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

Pues, parece ser que siempre es más eficiente el utilizar funciones nativas: http://ideone.com/ERE5WJ

Y la diferencia se hace más notoria (y preocupante) cuando el array contiene más elementos:

De cualquier modo, nuestro amigo zyxer aprendió más de una forma de hacer lo que buscaba.

Saludos

Última edición por Alexis88; 01/05/2014 a las 15:07 Razón: Otras fuentes
  #14 (permalink)  
Antiguo 04/05/2014, 11:18
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

Me quede pensando... tenia que haber una solucion eficiente y simple para tratar al ultimo elemento distinto ya sea en un foreach() o en una funcion de arrays.......

Código PHP:
Ver original
  1. function separar(&$arr)
  2. {
  3.     switch (count($arr))
  4.     {
  5.     case 0: return null;
  6.     case 1: return $arr[0];
  7.     default:   
  8.         $ult = array_pop($arr);
  9.         return implode (' ,',$arr).' y '.$ult;
  10.     }    
  11. }

Lamentablemente siempre existan 3 casos base y toca de alguna forma tratarlos (no elementos, 1 elemento, 2 o mas)
__________________
Salu2!
  #15 (permalink)  
Antiguo 04/05/2014, 11:35
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

La solución es buena, pero solamente resulta eficiente cuando el array contiene pocos elementos, pues cuando contiene muchos, que es lo común cuando se trabaja con BD, deja de serlo.

Por eso opté por no utilizar alguna estructura e ir directamente por las funciones nativas, porque, como alguna vez leí en este foro, este lenguaje no es muy eficiente que digamos.

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
  #16 (permalink)  
Antiguo 04/05/2014, 11:45
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

JO JO JO......Ud es un TRAMPOSO!!!! si Ud invierte el orden de las llamadas a las funciones la suya pierde lejos!!!!!!!!!!

Para 500:

Código resutlados pruebas:
Ver original
  1. Italico: 24.439208984375
  2. Alexis: 51.1572265625

y lo unico que hice fue cambiar el orden de las llamadas:

Código PHP:
Ver original
  1. <?php
  2. function italico(&$array)
  3. {
  4.     switch (count($array))
  5.     {
  6.     case 0: return null;
  7.     case 1: return $array[0];
  8.     default:    
  9.         $ult = array_pop($array);
  10.         return implode (' ,',$array).' y '.$ult;
  11.     }    
  12. }
  13.  
  14. function alexis($array) {
  15.     $string = implode(", ", $array);
  16.     return substr_replace ($string, " y ", strrpos($string, ","), 2);
  17. }
  18.  
  19. $array = range(1, 500);
  20.  
  21. $ini2 = microtime(true) * 1000;
  22. for ($i = 0; $i < 1000; $i++)
  23.     alexis($array);
  24. $fin2 = microtime(true) * 1000;
  25. $tiempoAlexis = $fin2 - $ini2;
  26.  
  27. $ini1 = microtime(true) * 1000;
  28. for ($i = 0; $i < 1000; $i++)
  29.     italico($array);
  30. $fin1 = microtime(true) * 1000;
  31. $tiempoItalico = $fin1 - $ini1;
  32.  
  33.  
  34.  
  35. echo "Italico: " . $tiempoItalico."\n";
  36. echo "Alexis: " . $tiempoAlexis;

El ultimo corre mas rapido ya que esos datos ya se procesaron y ni siquiera creando copias de los datos si son iguales el efecto "memoria" desaparece:

Código PHP:
Ver original
  1. <?php
  2. function italico1(&$arr)
  3.     {
  4.         $cant = count($arr);    
  5.    
  6.         if ($cant==0)  return null;        
  7.         $salida = null;
  8.        
  9.         if ($cant>1)
  10.         {
  11.             for ($i=0;$i<$cant-2;$i++)
  12.                 $salida .= $arr[$i].' ,';
  13.        
  14.             return $salida.$arr[$cant-2].' y '.$arr[$cant-1];  
  15.            
  16.         }else
  17.             return $arr[0];      
  18.    
  19.     }
  20.  
  21. function italico2(&$arr)
  22. {
  23.     switch (count($arr))
  24.     {
  25.     case 0: return null;
  26.     case 1: return $arr[0];
  27.     default:    
  28.         $ult = array_pop($arr);
  29.         return implode (' ,',$arr).' y '.$ult;
  30.     }    
  31. }
  32.  
  33. function alexis($array) {
  34.     $string = implode(", ", $array);
  35.     return substr_replace ($string, " y ", strrpos($string, ","), 2);
  36. }
  37.  
  38. $a[] = range(1, 500);
  39. $a[] = range(1, 500);
  40. $a[] = range(1, 500);
  41.  
  42.  
  43. $ini2 = microtime(true) * 1000;
  44. for ($i = 0; $i < 1000; $i++)
  45.     alexis($a[1]);
  46. $fin2 = microtime(true) * 1000;
  47. $tiempoAlexis = $fin2 - $ini2;
  48.  
  49. $ini1 = microtime(true) * 1000;
  50. for ($i = 0; $i < 1000; $i++)
  51.     italico1($a[0]);
  52. $fin1 = microtime(true) * 1000;
  53. $tiempoItalico1 = $fin1 - $ini1;
  54.  
  55. $ini1 = microtime(true) * 1000;
  56. for ($i = 0; $i < 1000; $i++)
  57.     italico2($a[2]);
  58. $fin1 = microtime(true) * 1000;
  59. $tiempoItalico2 = $fin1 - $ini1;
  60.  
  61.  
  62. echo "Italico (script #1): " . $tiempoItalico1."\n";
  63. echo "Italico (script #2): " . $tiempoItalico2."\n";
  64. echo "Alexis: " . $tiempoAlexis;

Puede probar...y si sigue cambiando de lugar las llamadas..... con los mismos datos, mismo "problema"
__________________
Salu2!

Última edición por Italico76; 04/05/2014 a las 11:55
  #17 (permalink)  
Antiguo 04/05/2014, 11:59
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

¿Tramposo? ¿Sabes que antes de ejecutar cada función, tomo el tiempo en milésimas de segundo que corresponda a ese momento? Hay que aprender a controlar el ego, mi estimado.

El cuerpo de benito
__________________
«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
  #18 (permalink)  
Antiguo 04/05/2014, 12:04
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

El post anterior se hizo largo (mucho codigo)..... voy a postear la solucion "justa" donde podras ver que si cambias el orden, el resultado cambia poco (porque de todas formas hay repeticion de valores)

Código PHP:
Ver original
  1. <?php
  2. function italico1(&$arr)
  3.     {
  4.         $cant = count($arr);    
  5.    
  6.         if ($cant==0)  return null;        
  7.         $salida = null;
  8.        
  9.         if ($cant>1)
  10.         {
  11.             for ($i=0;$i<$cant-2;$i++)
  12.                 $salida .= $arr[$i].' ,';
  13.        
  14.             return $salida.$arr[$cant-2].' y '.$arr[$cant-1];  
  15.            
  16.         }else
  17.             return $arr[0];      
  18.    
  19.     }
  20.  
  21. function italico2(&$arr)
  22. {
  23.     switch (count($arr))
  24.     {
  25.     case 0: return null;
  26.     case 1: return $arr[0];
  27.     default:    
  28.         $ult = array_pop($arr);
  29.         return implode (' ,',$arr).' y '.$ult;
  30.     }    
  31. }
  32.  
  33. function alexis($array) {
  34.     $string = implode(", ", $array);
  35.     return substr_replace ($string, " y ", strrpos($string, ","), 2);
  36. }
  37.  
  38. $a[] = range(1, 1000,2);
  39. $a[] = range(1, 1500,3);
  40. $a[] = range(1, 3500,7);
  41.  
  42. $ini1 = microtime(true) * 1000;
  43. for ($i = 0; $i < 1000; $i++)
  44.     italico1($a[0]);
  45. $fin1 = microtime(true) * 1000;
  46. $tiempoItalico1 = $fin1 - $ini1;
  47.  
  48. $ini1 = microtime(true) * 1000;
  49. for ($i = 0; $i < 1000; $i++)
  50.     italico2($a[2]);
  51. $fin1 = microtime(true) * 1000;
  52. $tiempoItalico2 = $fin1 - $ini1;
  53.  
  54. $ini2 = microtime(true) * 1000;
  55. for ($i = 0; $i < 1000; $i++)
  56.     alexis($a[1]);
  57. $fin2 = microtime(true) * 1000;
  58. $tiempoAlexis = $fin2 - $ini2;
  59.  
  60.  
  61.  
  62.  
  63. echo "Italico (script #1): " . $tiempoItalico1."\n";
  64. echo "Italico (script #2): " . $tiempoItalico2."\n";
  65. echo "Alexis: " . $tiempoAlexis;

En el orden que quieras.....

Cita:
Alexis: 55 seg aprox
Italico #1: 162 seg aprox
Italico #2: 25 seg aprox << winner
Asi que... es cierto que se puede ganar velocidad con funciones nativas y de hecho las he utilizado en la ultima version pero a difierencia tuya no recorro el arreglo varias veces con distintas funciones (nativas o no) y por eso a la final.......... gano :)
__________________
Salu2!
  #19 (permalink)  
Antiguo 04/05/2014, 12:10
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

Claro, campeón, tu "ganas".

http://ideone.com/ajHblr
__________________
«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
  #20 (permalink)  
Antiguo 04/05/2014, 12:31
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

Bueno...ahi la diferencia fue de 2 segundos apenas......

Declaremos el empate ;)
__________________
Salu2!
  #21 (permalink)  
Antiguo 04/05/2014, 12:37
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años
Puntos: 977
Respuesta: Reemplazar última coma por " y"

Jeje, como gustes (aunque ahí veo 4 segundos de diferencia ). Damos por concluido el tema.

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
  #22 (permalink)  
Antiguo 04/05/2014, 12:43
Avatar de Italico76  
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Reemplazar última coma por " y"

Antes del cierre... me doy por vencido:

lo corrí para 10.000 elementos.... y UFFF... ahi me das una buena paliza

Cita:
Italico (script #1): 3927.8950195312
Italico (script #2): 2406.8630371094
Alexis: 1203.8640136719
Y eso en este orden:

Código PHP:
Ver original
  1. $ini1 = microtime(true) * 1000;
  2. for ($i = 0; $i < 1000; $i++)
  3.     italico1($a);
  4. $fin1 = microtime(true) * 1000;
  5. $tiempoItalico1 = $fin1 - $ini1;
  6.  
  7. $ini2 = microtime(true) * 1000;
  8. for ($i = 0; $i < 1000; $i++)
  9.     alexis($a);
  10. $fin2 = microtime(true) * 1000;
  11. $tiempoAlexis = $fin2 - $ini2;  
  12.  
  13. $ini1 = microtime(true) * 1000;
  14. for ($i = 0; $i < 1000; $i++)
  15.     italico2($a);
  16. $fin1 = microtime(true) * 1000;
  17. $tiempoItalico2 = $fin1 - $ini1;

Ya no me explico porque tu funcion crece con un exponente menor que la mia en tiempo excepto que..... array_pop() sea una carreta


Mi conclusion: al escribir un codigo eficiente no solo hay que ser eficientes con la algoritmica sino tambien estudiosos para la eleccion de las funciones nativas
__________________
Salu2!

Última edición por Italico76; 04/05/2014 a las 13:11

Etiquetas: coma, reemplazar
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 05:21.