Foros del Web » Programando para Internet » PHP »

simular count group by para un array

Estas en el tema de simular count group by para un array en el foro de PHP en Foros del Web. que tal forer@s, traigo este problemilla, veran, tengo un arreglo mas o menos asi: $items = array( array("fecha"->"2014-05-26", "clave"->"11"), array("fecha"->"2014-05-26", "clave"->"10"), array("fecha"->"2014-05-26", "clave"->"06"), array("fecha"->"2014-05-26", "clave"->"10"), ...
  #1 (permalink)  
Antiguo 30/05/2014, 22:34
Avatar de catpaw  
Fecha de Ingreso: mayo-2010
Ubicación: xalapa
Mensajes: 856
Antigüedad: 14 años, 6 meses
Puntos: 23
simular count group by para un array

que tal forer@s,

traigo este problemilla, veran, tengo un arreglo mas o menos asi:

$items =
array(
array("fecha"->"2014-05-26", "clave"->"11"),
array("fecha"->"2014-05-26", "clave"->"10"),
array("fecha"->"2014-05-26", "clave"->"06"),
array("fecha"->"2014-05-26", "clave"->"10"),
array("fecha"->"2014-05-27", "clave"->"11"),
array("fecha"->"2014-05-27", "clave"->"06"),
array("fecha"->"2014-05-28", "clave"->"10"),
array("fecha"->"2014-05-28", "clave"->"10"),
array("fecha"->"2014-05-28", "clave"->"02"),
array("fecha"->"2014-05-28", "clave"->"01"),
array("fecha"->"2014-05-29", "clave"->"06"),
array("fecha"->"2014-05-29", "clave"->"02"),
array("fecha"->"2014-05-30", "clave"->"10"),
array("fecha"->"2014-05-30", "clave"->"03")
);

como se observa es una fecha y una clave, la fecha esta ordenada de menor a mayor.

la idea es obtener lo siguiente:

clave: 01
fecha: 2014-05-26
total:0
fecha: 2014-05-27
total:0
fecha: 2014-05-28
total:1
fecha: 2014-05-29
total:0
fecha: 2014-05-30
total:0

--

clave: 02
fecha: 2014-05-26
total:0
fecha: 2014-05-27
total:0
fecha: 2014-05-28
total:1
fecha: 2014-05-29
total:1
fecha: 2014-05-30
total:0

--

clave: 03
fecha: 2014-05-26
total:0
fecha: 2014-05-27
total:0
fecha: 2014-05-28
total:0
fecha: 2014-05-29
total:0
fecha: 2014-05-30
total:1

--

clave: 06
fecha: 2014-05-26
total:1
fecha: 2014-05-27
total:1
fecha: 2014-05-28
total:0
fecha: 2014-05-29
total:1
fecha: 2014-05-30
total:0

--

clave: 10
fecha: 2014-05-26
total:2
fecha: 2014-05-27
total:0
fecha: 2014-05-28
total:2
fecha: 2014-05-29
total:0
fecha: 2014-05-30
total:1

--

clave: 11
fecha: 2014-05-26
total:1
fecha: 2014-05-27
total:1
fecha: 2014-05-28
total:0
fecha: 2014-05-29
total:0
fecha: 2014-05-30
total:0

es decir, agrupar por clave y fecha y contar cuantos hay en cada uno.

mi idea es:

Código PHP:
$inicio "2014-05-26";
$fin "2014-05-30";
foreach(
$claves as $clave){
    for(
$i=$inicio;$i<=$fin;$i=date('Y-m-d'strtotime('+1 day'))){
        for(
$j=0;$j<count($items);$j++){
              if(
$items[$j]['fecha']==$i){
                    
$acomulado++;     
              }
        }
    }

pero de ahi ya no se como recabar la informacion como la necesito, ni donde reiniciar el acomulado.

primero recorro las claves, por cada clave, recorro las fechas desde la inicial y le voy sumando un dia hasta la fecha final, dentro de este ciclo recorro todo el arreglo items y pregunto si es la misma fecha entonces le acomulo uno.

el problema como ya dije es que ya no me imagino como recabar en otro arreglo la informacion que necesito y que si este metodo es bastante tardado y ademas cuando haya mas datos yo creo que va a tronar.

si ustedes tienen alguna sugerencia o aporte se los agradeceria mucho.
  #2 (permalink)  
Antiguo 31/05/2014, 05:24
Avatar de guardarmicorreo  
Fecha de Ingreso: noviembre-2012
Ubicación: Córdoba
Mensajes: 1.153
Antigüedad: 12 años
Puntos: 84
Respuesta: simular count group by para un array

¿Antes de meterte de lleno en solucionar este problema has pensado en cómo evitar este problema generando el array que deseas antes de reordenar este?
__________________
Ayúdame a hacerlo por mi mismo.
  #3 (permalink)  
Antiguo 31/05/2014, 05:51
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 16 años, 3 meses
Puntos: 2237
Respuesta: simular count group by para un array

Dudo que el for funcione con fechas como cadena, es mejor si lo haces con timestamp, que es numérico:

Código PHP:
Ver original
  1. $inicio = strtotime('2014-05-26');
  2. $fin = strtotime('2014-05-30');
  3. // Creas un array para los acumulados
  4. $acums = array();
  5.  
  6. // Llenas el array de acumulados, primero las claves
  7. for($x = 1; $x <= 11; $x ++) {
  8.     $clave = ($x < 10) ? "0$x" : "$x";
  9.     $acums[$clave] = array();
  10.     // Luego las fechas: (86400 = 1 día)
  11.     for($i = $incio; $i <= $fin; $i += 86400) {
  12.            $fecha = date('Y-m-d', $i);
  13.            $acums[$clave][$fecha] = 0;
  14.     }
  15. }
  16.  
  17. // Ahora recorres los items para sumar en $acums
  18. foreach($items as $item) {
  19.      // Estas variables son solo para que quede legible
  20.      $clave = $item['clave'];
  21.      $fecha = $item['fecha'];
  22.      // Incrementas el acumulado
  23.      $acums[$clave][$fecha] ++;
  24. }
  25.  
  26. // Ya quedó más o menos lo que necesitas
  27. var_dump($acums);

No sé si necesites realmente tener todo en una variable o solo quieras mostrarlo; incluso, si estás obteniendo la información desde base de datos, seguramente puede simplificarse desde la consulta.

Sin embargo, con la poca información que proporcionas, es difícil sugerir algo mejor.
__________________
- León, Guanajuato
- GV-Foto
  #4 (permalink)  
Antiguo 31/05/2014, 08:10
Avatar de catpaw  
Fecha de Ingreso: mayo-2010
Ubicación: xalapa
Mensajes: 856
Antigüedad: 14 años, 6 meses
Puntos: 23
Respuesta: simular count group by para un array

Hola!!

El arreglo no lo genero desde una consulta si fuera ese caso no habría problema, lo que necesito obtener es un arreglo que me diga la clave y tenga un subarreglo con los dias y el acomulado por dia, esto por cada clave.

por ejemplo.

array = (
array("clave"->"01", "data"->array(array("fecha"->"2014-05-26","acomulado"->0), array("fecha"->"2014-05-27","acomulado"->0)));
//por cada clave
);

triby voy a analizar tu ejemplo, pruebo y te comento.

Gracias
  #5 (permalink)  
Antiguo 31/05/2014, 12:38
lolainas
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: simular count group by para un array

Dices que ya viene ordenador por fecha, se me ocurre sacar un arreglo asi:
Código:
array(
    'clave1' => array(
        'fecha1' => numero_repeticiones,
        'fecha2' => numero_repeticiones,
        'fecha3' => numero_repeticiones,
    ),
    'clave2' => array(
        'fecha1' => numero_repeticiones,
        'fecha2' => numero_repeticiones,
        'fecha3' => numero_repeticiones,
    )
)
De esta manera:
Código PHP:
$items = [
    [
"fecha" => "2014-05-26""clave" => "11"],
    [
"fecha" => "2014-05-26""clave" => "10"],
    [
"fecha" => "2014-05-26""clave" => "06"],
    [
"fecha" => "2014-05-26""clave" => "10"],
    [
"fecha" => "2014-05-27""clave" => "11"],
    [
"fecha" => "2014-05-27""clave" => "06"],
    [
"fecha" => "2014-05-28""clave" => "10"],
    [
"fecha" => "2014-05-28""clave" => "10"],
    [
"fecha" => "2014-05-28""clave" => "02"],
    [
"fecha" => "2014-05-28""clave" => "01"],
    [
"fecha" => "2014-05-29""clave" => "06"],
    [
"fecha" => "2014-05-29""clave" => "02"],
    [
"fecha" => "2014-05-30""clave" => "10"],
    [
"fecha" => "2014-05-30""clave" => "03"]
];

function 
ordenar(array $items) {
    
$result = [];
    foreach (
$items as $i => $item) {
        
$clave = (int) $item['clave'];
        
$fecha $item['fecha'];
        
$result[$clave][$fecha] = isset($result[$clave][$fecha]) ? $result[$clave][$fecha] + 1// si quieres empezar de cero, 0
    
}
    return 
$result;
}

var_dump(ordenar($items)); 
Produce esta salida:
Código:
array (size=6)
  11 => 
    array (size=2)
      '2014-05-26' => int 1
      '2014-05-27' => int 1
  10 => 
    array (size=3)
      '2014-05-26' => int 2
      '2014-05-28' => int 2
      '2014-05-30' => int 1
  6 => 
    array (size=3)
      '2014-05-26' => int 1
      '2014-05-27' => int 1
      '2014-05-29' => int 1
  2 => 
    array (size=2)
      '2014-05-28' => int 1
      '2014-05-29' => int 1
  1 => 
    array (size=1)
      '2014-05-28' => int 1
  3 => 
    array (size=1)
      '2014-05-30' => int 1
A ver si así te sirve.
  #6 (permalink)  
Antiguo 31/05/2014, 13:39
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: simular count group by para un array

Cita:
Iniciado por Triby Ver Mensaje
Dudo que el for funcione con fechas como cadena, es mejor si lo haces con timestamp, que es numérico
solo como una curiosidad, es posible hacer que un for itere fechas:
Código PHP:
Ver original
  1. <?php
  2. for($i = strtotime($fecha = '2014-05-26'); $i <= strtotime('2014-05-30'); $i = strtotime($fecha = date('Y-m-d', $i+86400)))
  3. {
  4.     echo($fecha."<br>");
  5. }

por supuesto que internamente itera numeros, pero a efectos practicos puede hacerse esa abstraccion.

Otra forma es con la clase DatePeriod y foreach
Código PHP:
Ver original
  1. <?php
  2. $daterange = new DatePeriod(new DateTime( '2014-05-26' ), new DateInterval('P1D'), (new DateTime( '2014-05-30' ))->modify( '+1 day' ));
  3.  
  4. foreach($daterange as $date){
  5.     echo $date->format("Y-m-d") . "<br>";
  6. }
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #7 (permalink)  
Antiguo 31/05/2014, 18:27
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 16 años, 3 meses
Puntos: 2237
Respuesta: simular count group by para un array

Cita:
Iniciado por NSD
solo como una curiosidad, es posible hacer que un for itere fechas:
Ahí te falto completar la parte donde mencioné "como cadenas" y, de cualquier manera, este for funciona igual, con la salvedad que haces la conversión de cadena a timestamp en la misma sentencia, sin crear variables adicionales.

Me gusta mucho más tu segunda propuesta, realmente es buena.
__________________
- León, Guanajuato
- GV-Foto
  #8 (permalink)  
Antiguo 02/06/2014, 19:36
Avatar de catpaw  
Fecha de Ingreso: mayo-2010
Ubicación: xalapa
Mensajes: 856
Antigüedad: 14 años, 6 meses
Puntos: 23
Respuesta: simular count group by para un array

wow les agradezco mucho sus respuestas, todas le han dado luz a mi camino jeje, sigo en construcción, pero en cuanto quede les aviso.

NSD buenisimo lo del DatePeriod.

lolainas se ve muy prometedor tu ejemplo.

Gracias

Etiquetas: count, fecha, group, simular
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 18:08.