Agrupe los datos de la matriz 2d usando el valor de la columna para crear una matriz 3d

5 minutos de lectura

avatar de usuario de n00b0101
n00b0101

Tengo una matriz multidimensional y estoy tratando de agruparlos según el valor en una columna específica.

Estoy tratando de agruparlos por level, pero en realidad no sabré el nivel de antemano. Entonces, no es como si pudiera ponerlo en un for bucle y decir while $i < 7porque no lo sabré 7 es el valor máximo para la clave de nivel y, francamente, no estoy seguro de cómo tendría que hacerlo aunque lo hiciera.

[
    ['cust' => 'XT8900', 'type' => 'standard', 'level' => 1],
    ['cust' => 'XT8944', 'type' => 'standard', 'level' => 1],
    ['cust' => 'XT8922', 'type' => 'premier', 'level' => 3],
    ['cust' => 'XT8816', 'type' => 'permier', 'level' => 3],
    ['cust' => 'XT7434', 'type' => 'standard', 'level' => 7],
]

Resultado deseado:

Array (

   [1] => Array (
          [0] => Array (
                    [cust] => XT8900
                    [type] => standard
                    )
          [1] => Array (
                    [cust] => XT8944
                    [type] => standard
                    )
          )

   [3] => Array (
          [2] => Array (
                 [cust] => XT8922
                 [type] => premier
                 )

          [3] => Array (
                 [cust] => XT8816
                 [type] => permier
                 )
          )

   [7] => Array (
          [4] => Array (
                 [cust] => XT7434
                 [type] => standard
                 )
          )
)

La mejor manera, si tiene control sobre la construcción de la matriz inicial, es configurar las cosas así al principio a medida que agrega entradas.

De lo contrario, cree una matriz temporal para ordenar:

foreach ($input_arr as $key => &$entry) {
    $level_arr[$entry['level']][$key] = $entry;
}

Te deja con el formulario que querías y todo referenciado junto.

Construya la matriz así en primer lugar, si es posible.

  • No entiendo el beneficio de hacer $entry una referencia.

    – mickmackusa

    10 de febrero a las 5:21

  • @mickmackusa foreach hace una copia de la matriz sobre la que está iterando en algunas circunstancias. Ser explícito sobre el uso de una referencia significa que puede estar seguro de que no está copiando lo que podría ser una enorme matriz de entrada. No sé si esa microoptimización es relevante en 2023, el mundo era mucho más joven cuando originalmente escribí esta respuesta 🙂

    – Miguel

    12 de febrero a las 12:49

Avatar de usuario de Gerard Banasig
Gerard Banasig

Tienes que agruparlos por nivel primero

Usar para cada para hacer un bucle en la matriz, verifique si el nivel es el mismo que el elemento anterior y luego agrúpelo con esa matriz

  $templevel=0;   

  $newkey=0;

  $grouparr[$templevel]="";

  foreach ($items as $key => $val) {
   if ($templevel==$val['level']){
     $grouparr[$templevel][$newkey]=$val;
   } else {
     $grouparr[$val['level']][$newkey]=$val;
   }
     $newkey++;       
  }
print($grouparr);

la salida de imprimir($agruparr); se mostrará como el formato que esperaba

También puedes intentar

print($grouparr[7]);

Mostrará

 [7] => Array (
      [4] => Array (
             [cust] => XT7434
             [type] => standard
             )
      )

O

print($grouparr[3]);

Mostrará

[3] => Array (
      [2] => Array (
             [cust] => XT8922
             [type] => premier
             )

      [3] => Array (
             [cust] => XT8816
             [type] => permier
             )
      )

  • Creo que la cláusula ‘si’ en su código anterior es redundante, ya que la línea ” $grouparr[$val[‘level’]][$newkey]=$valor; ” funciona para todos los casos. En otras palabras, esta línea es válida también para el caso de que ‘$templevel’ sea igual a ‘$val[‘level’]’. Entonces, en ese caso, el código sería simplemente: $templevel=0; $nuevaclave=0; foreach ($elementos como $clave => $val) { $grouparr[$val[‘level’]][$newkey]=$valor; $nuevaclave++; } imprimir ($ grupo arr);

    – vasilis

    28 oct 2020 a las 10:40


Aquí está la solución que encontré para un problema idéntico, envuelta como una función:

function arraySort($input,$sortkey){
  foreach ($input as $key=>$val) $output[$val[$sortkey]][]=$val;
  return $output;
}

Para ordenar $myarray por la clave llamada “nivel” simplemente haga esto:

$myArray = arraySort($myArray,'level');

O si no lo quisiera como una función, solo para un uso único, esto crearía $myNewArray a partir de $myArray agrupados por la clave ‘nivel’

foreach ($myArray as $key=>$val) $myNewArray[$val['level']][]=$val;

  • esta es una respuesta tan útil. Estoy tratando de usar esto pero para que $val sea un valor único. ¿Sugerencias?

    – dibujó schmaltz

    22 de abril de 2014 a las 4:31

  • Esta respuesta no proporciona el resultado deseado del OP porque no está incrementando las claves del subarreglo. Prueba: sandbox.onlinephpfunctions.com/code/…

    – mickmackusa

    24 de agosto de 2018 a las 3:17

function group_assoc($array, $key) {
    $return = array();
    foreach($array as $v) {
        $return[$v[$key]][] = $v;
    }
    return $return;
}

//Group the requests by their account_id
$account_requests = group_assoc($requests, 'account_id');

  $result = array();
    foreach ($yourArrayList as $data) {
        $id = $data['level'];
        if (isset($result[$id])) {
            $result[$id][] = $data;
        } else {
            $result[$id] = array($data);
        }
    }

  • Las respuestas de solo código tienen poco valor en StackOverflow porque hacen un mal trabajo al educar al OP y a los futuros investigadores: cada respuesta (incluso las básicas) debe incluir algún tipo de explicación sobre cómo funciona la solución y por qué es recomendable. Esta respuesta NO proporciona el resultado deseado según lo dictado por la pregunta porque no incrementa las claves del subarreglo. Prueba: sandbox.onlinephpfunctions.com/code/…

    – mickmackusa

    24 de agosto de 2018 a las 3:21

Avatar de usuario de VIPAN KUMAR
VIPAN KUMAR

mejor respuesta

    $levels = array_unique(array_column($records, 'level'));

    $data = array();

    foreach($records as $key => $value){ 

    $data[$levels[array_search($value['level'],$levels )]][] = $value ; 

    }

    print_r($data); 

  • Las respuestas de solo código tienen poco valor en StackOverflow porque hacen un mal trabajo al educar al OP y a los futuros investigadores: cada respuesta (incluso las básicas) debe incluir algún tipo de explicación sobre cómo funciona la solución y por qué es recomendable. Esta respuesta NO proporciona el resultado deseado según lo dictado por la pregunta porque no incrementa las claves del subarreglo. Prueba: sandbox.onlinephpfunctions.com/code/…

    – mickmackusa

    24 de agosto de 2018 a las 3:21

avatar de usuario de mickmackusa
mickmackusa

Para generar la salida deseada exacta de la pregunta a partir de la entrada de muestra, extraiga/haga clic en el último valor de cada fila, use ese valor como la clave de agrupación de primer nivel. A continuación, utilice el índice de primer nivel original como clave de segundo nivel. Luego inserte los dos elementos restantes en el subconjunto del grupo.

Código: (Manifestación)

$result = [];
foreach ($array as $key => $row) {
    $result[array_pop($row)][$key] = $row;
}
var_export($result);

Para la sintaxis de estilo funcional, utilice array_reduce(). (Manifestación)

var_export(
    array_reduce(
        array_keys($array),
        function($result, $key) use ($array) {
            $result[array_pop($array[$key])][$key] = $array[$key];
            return $result;
        }
    )
);

¿Ha sido útil esta solución?