I'm trying to sort a multidimensional array with an extra flag. The array got childs with name and a optional checked flag. I want to sort this array by checked, and then name. I've got this working fine on the name part, but I can't seem to get the checked flag in it.
<?php
$data = array(
array(
'name' => 'C'
),
array(
'name' => 'A'
),
array(
'name' => 'E',
'checked' => true
),
array(
'name' => 'B',
'checked' => true
),
array(
'name' => 'F'
),
array(
'name' => 'D'
)
);
usort($data, function($a, $b) {
return strcmp($a['name'], $b['name']);
});
For the record: I want this as the result: B E A C D F
Any help would be appreciated.
Within usort
you can "prioritize" the checked flag:
usort($data, function($a, $b) {
$diff = strcmp($a['name'], $b['name']);
if (isset($a['checked']) && isset($b['checked'])) return $diff;
if (isset($a['checked'])) return -1;
if (isset($b['checked'])) return 1;
return $diff;
});
If you ever add in 'checked' => false
attributes, you'd have to change the logic accordingly.
Split the array into two parts (checked and not), sort separately, and merge the result:
function filterAndSort($array, $checked = true) {
$array = array_filter($array, function ($a) use ($checked) {
return $checked ? isset($a['checked']) : !isset($a['checked']);
});
usort($array, function($a, $b) {
return strcmp($a['name'], $b['name']);
});
return $array;
}
$data = array_merge(filterAndSort($data, true), filterAndSort($data, false));
print_r($data);
Outputs:
Array(
[0] => Array(
[name] => B
[checked] => 1
)
[1] => Array(
[name] => E
[checked] => 1
)
[2] => Array(
[name] => A
)
[3] => Array(
[name] => C
)
[4] => Array(
[name] => D
)
[5] => Array(
[name] => F
)
)