I'm trying to order this multidimensional array, with no success. I need to sort ascending by pub_obs
but keeping the main array order (AC, BA, ..). The indexes inside the main arrays (0, 1, 2, ..) can change but the pub_id
have to be the same.
Array(
[AC] => Array
(
[0] => Array
(
[pub_id] => 1
[pub_obs] => c
)
[1] => Array
(
[pub_id] => 3
[pub_obs] => a
)
[2] => Array
(
[pub_id] => 4
[pub_obs] => c
)
)
[BA] => Array
(
[0] => Array
(
[pub_id] => 1
[pub_obs] => b
)
[1] => Array
(
[pub_id] => 2
[pub_obs] => b
)
[2] => Array
(
[pub_id] => 7
[pub_obs] => a
)
)
)
Somebody can help? Thanks!
Edit
I forgot to say about the PHP version, 5.2, but @fusion3k was quick! thanks for the answer dude and for everybody who helped too!
Use a foreach
with main array by reference, then usort
fore each row:
foreach( $array as &$row )
{
usort
(
$row,
function( $a, $b )
{
return strcmp($a['pub_obs'], $b['pub_obs']);
}
);
}
Output:
Array
(
[AC] => Array
(
[0] => Array
(
[pub_id] => 3
[pub_obs] => a
)
[1] => Array
(
[pub_id] => 4
[pub_obs] => c
)
[2] => Array
(
[pub_id] => 1
[pub_obs] => c
)
)
[BA] => Array
(
[0] => Array
(
[pub_id] => 7
[pub_obs] => a
)
[1] => Array
(
[pub_id] => 2
[pub_obs] => b
)
[2] => Array
(
[pub_id] => 1
[pub_obs] => b
)
)
)
Using references in the foreach the usort
function act directly on main array, then in custom function compare pub_id
keys to define nested sort order.
The above method works, as requested in the question. However, if we have a sub-array like this one:
[
[ 'pub_id' => 1, 'pub_obs' => 'b' ],
[ 'pub_id' => 2, 'pub_obs' => 'b' ],
[ 'pub_id' => 3, 'pub_obs' => 'a' ]
]
the output is:
Array
(
[0] => Array
(
[pub_id] => 3
[pub_obs] => a
)
[1] => Array
(
[pub_id] => 2
[pub_obs] => b
)
[2] => Array
(
[pub_id] => 1
[pub_obs] => b
)
)
The requested keys are correctly sorted, but — on same pub_obs
value — pub_id
order is not maintained.
To avoid this, you have to sub-process even the pub_id
key:
usort
(
$row,
function( $a, $b )
{
$mainCmp = strcmp( $a['pub_obs'], $b['pub_obs'] );
if( !$mainCmp )
{
return( strcmp( $a['pub_id'], $b['pub_id'] ) );
}
else return $mainCmp;
}
);
Simply define a custom function with same content of above anonymous function:
function myCompare( $a, $b )
{
$mainCmp = strcmp( $a['pub_obs'], $b['pub_obs'] );
if( !$mainCmp )
{
return( strcmp( $a['pub_id'], $b['pub_id'] ) );
}
else
return $mainCmp;
}
and then call it inside the foreach()
loop:
foreach( $array as &$row )
{
usort( $row, 'myCompare' );
}
PS: Thank you to @deceze for previous edit (maintained here).
You can use the aasort from this answer: Sort Multi-dimensional Array by Value and apply it to each array row:
function aasort (&$array, $key) {
$sorter=array();
$ret=array();
reset($array);
foreach ($array as $ii => $va) {
$sorter[$ii]=$va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii]=$array[$ii];
}
$array=$ret;
}
//Now your array
foreach($array as $key => &$value){
aasort($value,"pub_obs");
}