2010-03-19 11 views
80

tengo la siguiente structue de matriz:PHP Ordenar matriz por subarreglo Valor

Array 
     (
      [0] => Array 
       (
        [configuration_id] => 10 
        [id] => 1 
        [optionNumber] => 3 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 

      [1] => Array 
       (
        [configuration_id] => 9 
        [id] => 1 
        [optionNumber] => 2 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 

      [2] => Array 
       (
        [configuration_id] => 8 
        [id] => 1 
        [optionNumber] => 1 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 
    ) 

¿Cuál es la mejor manera para la orden de la matriz, de manera incremental basado en el optionNumber?

lo que los resultados se ven como:

Array 
     (
      [0] => Array 
       (
        [configuration_id] => 8 
        [id] => 1 
        [optionNumber] => 1 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 

      [1] => Array 
       (
        [configuration_id] => 9 
        [id] => 1 
        [optionNumber] => 2 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 

      [2] => Array 
       (
        [configuration_id] => 10 
        [id] => 1 
        [optionNumber] => 3 
        [optionActive] => 1 
        [lastUpdated] => 2010-03-17 15:44:12 
       ) 
    ) 

Respuesta

152

Uso usort.

function cmp_by_optionNumber($a, $b) { 
    return $a["optionNumber"] - $b["optionNumber"]; 
} 

... 

usort($array, "cmp_by_optionNumber"); 

En PHP ≥5.3, se debe utilizar una vez anonymous function:

usort($array, function ($a, $b) { 
    return $a['optionNumber'] - $b['optionNumber']; 
}); 

Tenga en cuenta que tanto el código de asumir $a['optionNumber'] es un entero. Use @St. John Johnson's solution si son cadenas.


En PHP ≥7.0, utilice el spaceship operator <=> en lugar de la resta para evitar problemas de desbordamiento/truncamiento.

usort($array, function ($a, $b) { 
    return $a['optionNumber'] <=> $b['optionNumber']; 
}); 
+1

que en realidad no me HELPE como usort requiere que proporcionan una función de usar - que es el poco difícil no puedo conseguir mi cabeza redonda – Sjwdavies

+11

Bueno, él sólo le dio la función usar. Y tendrá que aceptar que no siempre hay una función incorporada para hacer lo que quiere, tiene que escribirla usted mismo. Las funciones de comparación solo requieren un retorno de 1, 0 o -1 que indique el orden de clasificación de dos elementos. – Tesserex

+1

Busqué más en usort y en realidad es bastante genial. Escribí una función de comparación simple a la anterior, sin embargo me perdí el '=='. Gracias por la ayuda muchachos – Sjwdavies

48

Uso usort

usort($array, 'sortByOption'); 
function sortByOption($a, $b) { 
    return strcmp($a['optionNumber'], $b['optionNumber']); 
} 
+0

Este me funcionó. @ KennyTM no pareció funcionar –

+7

@BenSinclair, porque la solución de Kenny es para números, esta solución es para cadenas. Ambos son correctos :-) +1 para esta alternativa. – kubilay

+0

Funcionó para mí, porque estaba ordenando cadenas ... – Andy

4

Las claves se eliminan cuando se utiliza una función como los de arriba. Si las claves son importantes, la siguiente función lo mantendría ... pero los bucles foreach son bastante ineficientes.

function subval_sort($a,$subkey) { 
    foreach($a as $k=>$v) { 
     $b[$k] = strtolower($v[$subkey]); 
    } 
    asort($b); 
    foreach($b as $key=>$val) { 
     $c[$key] = $a[$key]; 
    } 
    return $c; 
} 
$array = subval_sort($array,'optionNumber'); 

Utilice arsort en lugar de asort si lo desea de mayor a menor.

de crédito

Código: http://www.firsttube.com/read/sorting-a-multi-dimensional-array-with-php/

3

PHP 5.3+

usort($array, function($a,$b){ return $a['optionNumber']-$b['optionNumber'];}); 
11

que utilizan ambas soluciones por KennyTM y AJ Quick y se acercó con una función que puede ayudar en este tema desde hace muchos casos como usando ASC o DESC clasificación o preservando las claves o si tiene objetos como hijos de la matriz.

aquí es la siguiente función:

/** 
* @param array $array 
* @param string $value 
* @param bool $asc - ASC (true) or DESC (false) sorting 
* @param bool $preserveKeys 
* @return array 
* */ 
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false) 
{ 
    if ($preserveKeys) { 
     $c = array(); 
     if (is_object(reset($array))) { 
      foreach ($array as $k => $v) { 
       $b[$k] = strtolower($v->$value); 
      } 
     } else { 
      foreach ($array as $k => $v) { 
       $b[$k] = strtolower($v[$value]); 
      } 
     } 
     $asc ? asort($b) : arsort($b); 
     foreach ($b as $k => $v) { 
      $c[$k] = $array[$k]; 
     } 
     $array = $c; 
    } else { 
     if (is_object(reset($array))) { 
      usort($array, function ($a, $b) use ($value, $asc) { 
       return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} - $b->{$value}) * ($asc ? 1 : -1); 
      }); 
     } else { 
      usort($array, function ($a, $b) use ($value, $asc) { 
       return $a[$value] == $b[$value] ? 0 : ($a[$value] - $b[$value]) * ($asc ? 1 : -1); 
      }); 
     } 
    } 

    return $array; 
} 

Uso:

sortBySubValue($array, 'optionNumber', true, false); 

Editar

La primera parte se puede reescribir usando uasort() y la functi en adelante será más corto:

/** 
* @param array $array 
* @param string $value 
* @param bool $asc - ASC (true) or DESC (false) sorting 
* @param bool $preserveKeys 
* @return array 
* */ 
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false) 
{ 
    if (is_object(reset($array))) { 
     $preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) { 
      return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} - $b->{$value}) * ($asc ? 1 : -1); 
     }) : usort($array, function ($a, $b) use ($value, $asc) { 
      return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} - $b->{$value}) * ($asc ? 1 : -1); 
     }); 
    } else { 
     $preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) { 
      return $a[$value] == $b[$value] ? 0 : ($a[$value] - $b[$value]) * ($asc ? 1 : -1); 
     }) : usort($array, function ($a, $b) use ($value, $asc) { 
      return $a[$value] == $b[$value] ? 0 : ($a[$value] - $b[$value]) * ($asc ? 1 : -1); 
     }); 
    } 
    return $array; 
} 
+0

Esta es la mejor respuesta más útil aquí, debe estar en la parte superior;) –

+0

@EdiBudimilic gracias, lo aprecio! Por cierto, he actualizado mi respuesta y he agregado una versión más corta de esta función :) –

+1

Para que esto funcione para mí, tuve que usar '>' (mayor que) en lugar de '-' (menos) al comparar' $ a' y '$ b' valores ya que estaba comparando cadenas. Aún así funciona. – James

Cuestiones relacionadas