Eliminar duplicados / ordenar de una matriz de matrices asociativas en PHP

Tengo una matriz de matrices asociativas

 aa [] = ('Llantas' => 100, 'Aceite' => 10, 'Bujías' => 4);
 aa [] = ('Llantas' => 454, 'Aceite' => 43, 'Bujías' => 3);
 aa [] = ('Tires' => 34, 'Oil' => 55, 'Spark Plugs' => 44);
 aa [] = ('Llantas' => 454, 'Aceite' => 43, 'Bujías' => 45);
 aa [] = ('Llantas' => 34, 'Aceite' => 55, 'Bujías' => 433);
 aa [] = ('Tires' => 23, 'Oil' => 33, 'Spark Plugs' => 44);

Dos preguntas

  1. ¿Cómo puedo eliminar duplicados de acuerdo con el campo ‘Oil’? ¿Existe un array_unique que puedo proporcionar una callback que actúa como un comparador personalizado?

  2. ¿Cómo puedo ordenar por un campo personalizado ‘Spark Plugs’?

  1. No sé de una función que pueda usar para hacer esto. Tendrá que hacer un foreach sobre los valores de la matriz y hacer la comprobación de exclusividad manualmente.

  2. Use la función usort () y proporcione un comparador personalizado.

En lugar de ir manualmente y hacer la comprobación duplicada habitual, hice esto



 $ aa2 = array ()

 foeach ($ aa como $ clave => $ valor) {
   $ aa2 [$ value ['Oil']] = $ value;
 }
 $ aa = $ aa2;

Luego, la clasificación se hizo con la clave …

Para la pregunta 1, creo que array_filter es lo que necesitas.

Y, como dice Brian, solicite su segunda pregunta.

El problema con eliminar a los engañados de esta manera es cómo determinar qué valores permanecen, ya que estás hablando de exclusividad parcial.

Esta solución a continuación solo mantiene el primero en aparecer en orden de índice. No es exactamente elegante, pero funciona.

100, 'Oil'=>10, 'Spark Plugs'=>4 ); $aa[] = array('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>3 ); $aa[] = array('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>44 ); $aa[] = array('Tires'=>454, 'Oil'=>43, 'Spark Plugs'=>45 ); $aa[] = array('Tires'=>34, 'Oil'=>55, 'Spark Plugs'=>433 ); $aa[] = array('Tires'=>23, 'Oil'=>33, 'Spark Plugs'=>44 ); echo '
'; print_r( arrayUniqeBySubKey( $aa, 'Oil' ) ); echo '

'; function arrayUniqeBySubKey( $array, $key ) { $indexAggregates = array(); foreach ( $array as $idx => $subArray ) { $indexAggregates[$subArray[$key]][] = $idx; } foreach ( $indexAggregates as $originalIndexes ) { $numOriginals = count( $originalIndexes ); if ( 1 == $numOriginals ) { continue; } for ( $i = 1; $i < $numOriginals; $i++ ) { unset( $array[$originalIndexes[$i]] ); } } return $array; }

De hecho, puedes usar array_filter para filtrar tus datos:

 $bb = array_filter($aa, function($item) { static $tmp = array(); if ($filter = !in_array($item['Oil'], $tmp)) { $tmp[] = $item['Oil']; } return $filter; }); 

Utiliza una variable estática dentro de la función para “recordar” el aceite ya devuelto. Esto funciona, porque $ tmp se usa solo durante la ejecución de array_filter . Si ajusta esto en una función y lo llama varias veces, por ejemplo, $ tmp siempre será una matriz vacía para la primera llamada de la función proporcionada a array_filter .

La segunda tarea, la clasificación, se puede hacer utilizando usort con una función de clasificación personalizada:

 usort($bb, function($a, $b) { return ($a['Spark Plugs'] > $b['Spark Plugs'] ? 1 : -1); });