kishram kishram -4 years ago 79
PHP Question

Sorting a associative array based on two keys

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.

Answer Source

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
        )

)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download