I have an array that looks something like this:
$array = [
'field1' => [
'#type' => 'text',
'#label' => 'Field 11',
],
'field4' => [
'#type' => 'fieldset',
'#label' => 'Field 4',
],
'field12' => [
'#type' => 'text',
'#label' => 'Field 12',
],
'field3' => [
'#type' => 'fieldset',
'#label' => 'Field 3',
],
'field18' => [
'#type' => 'text',
'#label' => 'Field 18',
],
];
I would like to sort this array in such a way where all the fields of type fieldset
are at the bottom. At the same time, I would like the text fields (which are on top) to be sorted alphabetically by the #label
and the fieldsets (which should be at the bottom) should also be sorted alphabetically by the label. This is what I had so far.
ksort($array);
uasort($array, function($field1) {
if ($field1['#type'] !== 'fieldset') {
return 0;
}
return 1;
});
Sorting the array by the key value successfully sorts my entire array alphabetically. But once I add the uasort
, although my fieldset
's are at the bottom, the alphabetical order is no longer present.
Any ideas?
Use usort with 2 conditions
usort($array, function ($i1, $i2) {
// compare types
$r = ($i1['#type'] == 'fieldset' ? 1 : 0) - ($i2['#type'] == 'fieldset' ? 1 : 0);
// if both are (or not) fieldset (r == 0), compare labels
return $r ? $r : strcmp($i1['#label'], $i2['#label']); } );
I would use array_multisort
. This sorts as requested if you only have fieldset
and text
:
array_multisort(array_column($array, '#type'), SORT_DESC,
array_column($array, '#label'), SORT_ASC,
$array);
Extract all #type
values into an array sort descending and extract all #label
values into an array sort ascending, sorting the original.