Reputation: 103
I want to sort the id field by pushing array record with null value to bottom. If id value is present, then sort the col_1 by asc.
I have a multidimensional array like this.
Array
(
[0]=> Array
(
[id]=>1166
[col_1]=>9.4
)
[1]=> Array
(
[id]=>
[col_1]=>2.4
)
[2]=> Array
(
[id]=>1012
[col_1]=>0.96
)
[3]=> Array
(
[id]=>1856
[col_1]=>7.47
)
)
I want to sort it by id as well as col_1. I tried
foreach ($arr as $key => $row) {
$x[$key] = $row['id'];
$y[$key] = $row['col_1'];
}
array_multisort($x, SORT_DESC, $y, SORT_ASC, $arr);
I got the following as my result
Array
(
[0]=> Array
(
[id]=>1856
[col_1]=>7.47
)
[1]=> Array
(
[id]=>1166
[col_1]=>9.4
)
[2]=> Array
(
[id]=>1012,
[col_1]=>0.96
)
[3]=> Array
(
[id]=>
[col_1]=>2.47
)
)
But I want the result as,
Array
(
[0]=> Array
(
[id]=>1012
[col_1]=>0.96
)
[1]=> Array
(
[id]=>1856
[col_1]=>7.47
)
[2]=> Array
(
[id]=>1166
[col_1]=>9.4
)
[3]=> Array
(
[id]=>
[col_1]=>2.4
)
)
'id' field can be null also for some records. But col_1 will be there for all the records.
Upvotes: 1
Views: 69
Reputation: 42984
Not exactly sophisticated, but readable and straight forward:
<?php
$data = [
[
'id' => 1166,
'col_1' => 9.4
],
[
'id' => null,
'col_1' => 2.4
],
[
'id' => 1012,
'col_1' => 0.96
],
[
'id' => 1856,
'col_1' => 7.47
]
];
usort($data, function($a, $b) {
return ($a['col_1']>$b['col_1']);
});
usort($data, function($a) {
return !isset($a['id']);
});
print_r($data);
The output obviously is:
Array
(
[0] => Array
(
[id] => 1012
[col_1] => 0.96
)
[1] => Array
(
[id] => 1856
[col_1] => 7.47
)
[2] => Array
(
[id] => 1166
[col_1] => 9.4
)
[3] => Array
(
[id] =>
[col_1] => 2.4
)
)
In your comment below you now make an additional requirement. I doubt there is a direct way to evaluate both requirements in a straight forward sorting approach. So why not try a readable and obvious one:
<?php
$data = [
[
'id' => 1166,
'col_1' => 9.4
],
[
'id' => null,
'col_1' => 2.4
],
[
'id' => null,
'col_1' => 0.2
],
[
'id' => 1012,
'col_1' => 0.96
],
[
'id' => null,
'col_1' => 12
],
[
'id' => 1856,
'col_1' => 7.47
]
];
usort($data, function($a, $b) {
return ($a['col_1']>$b['col_1']);
});
$withId = array_filter($data, function($entry) {
return isset($entry ['id']);
});
$withoutId = array_filter($data, function($entry) {
return !isset($entry ['id']);
});
$data = array_merge($withId, $withoutId);
print_r($data);
The output obviously is:
Array
(
[0] => Array
(
[id] => 1012
[col_1] => 0.96
)
[1] => Array
(
[id] => 1856
[col_1] => 7.47
)
[2] => Array
(
[id] => 1166
[col_1] => 9.4
)
[3] => Array
(
[id] =>
[col_1] => 0.2
)
[4] => Array
(
[id] =>
[col_1] => 2.4
)
[5] => Array
(
[id] =>
[col_1] => 12
)
)
Upvotes: 2
Reputation: 1757
you can use the usort function to make a custom sort.
function customSort($a, $b) {
if (null === $a['id'] && null === $b['id']) {
return 0;
}
if (null === $a['id']) {
return 1;
}
if (null === $b['id']) {
return -1;
}
return ($a['col_1'] < $b['col_1']) ? -1 : 1;
}
$array = [
[
'id' => 1012,
'col_1' => 0.96
],
[
'id' => 1856,
'col_1' => 7.47
],
[
'id' => null,
'col_1' => 2.4
],
[
'id' => 1166,
'col_1' => 9.4
],
];
usort($array, 'customSort');
print_r($array);
This returns
Array
(
[0] => Array
(
[id] => 1012
[col_1] => 0.96
)
[1] => Array
(
[id] => 1856
[col_1] => 7.47
)
[2] => Array
(
[id] => 1166
[col_1] => 9.4
)
[3] => Array
(
[id] =>
[col_1] => 2.4
)
)
Which is what you expected. Hope this helped.
Upvotes: 1