Home > Back-end >  PHP sorting array of non-associative arrays but having string values at the beginning
PHP sorting array of non-associative arrays but having string values at the beginning

Time:07-08

 $unresponsives =   [
    [
        "Customer",
        "172.52.46.75",
        "2022-04-01 16:20:45",
        "1817",
        "nxlog",
        "2327.02 Hours"
    ],
    [
        "Customer",
        "172.25.89.45",
        "2022-04-01 16:20:45",
        "1817",
        "nxlog",
        "2327.02 Hours"
    ],
    [
        "Customer",
        "172.19.10.94",
        "2022-04-01 16:20:45",
        "1817",
        "nxlog",
        "2327.02 Hours"
    ]]

This is an example from my array of arrays. I want to sort the arrays inside by their fifth element (hours) in descending order. I am able to achieve this with usort but in the array there are also arrays with the string "Undefined" as their fifth value. Example below:

[
        "PreProd",
        "178.18.15.12",
        "\/",
        "1502",
        "iis",
        "Undefined"
    ]

Currently they are listed at the bottom of the array after the sorting is done. I instead want them to be listed in the beginning of the array. So first arrays with undefined ones and then the rest in descending order. How can I achieve this?

Below is the usort function that I use:

usort($unresponsives, function ($unresponsive1, $unresponsive2) {
            return floatval($unresponsive2[5]) <=> floatval($unresponsive1[5]);
        });

CodePudding user response:

You can no longer get away with returning a boolean for the usort function. So you need something like this

$unresponsives = [
    [
        "Customer", "172.52.46.75", "2022-04-01 16:20:45", "1817", "nxlog",
        "2327.02 Hours",
    ],
    [
        "Customer", "172.25.89.45", "2022-04-01 16:20:45", "1817", "nxlog",
        "5327.02 Hours",
    ],
    [
        "Customer", "172.19.10.94", "2022-04-01 16:20:45", "1817", "nxlog",
        "undefined",
    ],
];

usort($unresponsives, function ($a, $b) {
    if ($a[5] == $b[5]) {
        return 0;
    }
    return ($b[5] < $a[5]) ? -1 : 1;
});
print_r($unresponsives);

RESULTS

PHP 8.1.8

PHP 8.1.8
D:\PHP-SOURCE\Testing
Array
(
    [0] => Array
        (
            [0] => Customer
            [1] => 172.19.10.94
            [2] => 2022-04-01 16:20:45
            [3] => 1817
            [4] => nxlog
            [5] => undefined
        )

    [1] => Array
        (
            [0] => Customer
            [1] => 172.25.89.45
            [2] => 2022-04-01 16:20:45
            [3] => 1817
            [4] => nxlog
            [5] => 5327.02 Hours
        )

    [2] => Array
        (
            [0] => Customer
            [1] => 172.52.46.75
            [2] => 2022-04-01 16:20:45
            [3] => 1817
            [4] => nxlog
            [5] => 2327.02 Hours
        )

)

CodePudding user response:

For a slightly more complex approach that allows fine-grained control of the sorting as desired. Use array_column to retrieve the hours. Use array_keys on the hours to determine the filtered value positions and iterate over the positions to assign them as a numeric value. Then array_multisort can be used with the desired flags to sort the resulting arrays.

Example https://3v4l.org/SuJQX

$hours = array_column($unresponsives, 5);
if ($undefined = array_keys($hours, 'Undefined')) { 
    $hours = array_replace($hours, array_fill_keys($undefined, PHP_INT_MAX));
}
array_multisort($hours, SORT_DESC, SORT_NUMERIC, $unresponsives);

Result

var_export($unresponsives);

array (
  0 => 
  array (
    0 => 'Customer',
    1 => '172.19.10.94',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => 'Undefined',
  ),
  1 => 
  array (
    0 => 'Customer',
    1 => '172.25.89.45',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => 'Undefined',
  ),
  2 => 
  array (
    0 => 'Customer',
    1 => '172.52.46.75',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => '2328.02 Hours',
  ),
  3 => 
  array (
    0 => 'Customer',
    1 => '172.19.10.94',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => '2324.02 Hours',
  ),
  4 => 
  array (
    0 => 'Customer',
    1 => '172.19.10.94',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => '2322.02 Hours',
  ),
)

Ascending Numeric Sorting

To change the sort order to SORT_ASC swap out PHP_INT_MAX for PHP_INT_MIN, depending on where in the array you want the filtered value to reside.

$hours = array_column($unresponsives, 5);
if ($undefined = array_keys($hours, 'Undefined')) {    
    $hours = array_replace($hours, array_fill_keys($undefined, PHP_INT_MIN));
}
array_multisort($hours, SORT_ASC, SORT_NUMERIC, $unresponsives);

Result

var_export($unresponsives);

array (
  0 => 
  array (
    0 => 'Customer',
    1 => '172.19.10.94',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => 'Undefined',
  ),
  1 => 
  array (
    0 => 'Customer',
    1 => '172.25.89.45',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => 'Undefined',
  ),
  2 => 
  array (
    0 => 'Customer',
    1 => '172.19.10.94',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => '2322.02 Hours',
  ),
  3 => 
  array (
    0 => 'Customer',
    1 => '172.19.10.94',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => '2324.02 Hours',
  ),
  4 => 
  array (
    0 => 'Customer',
    1 => '172.52.46.75',
    2 => '2022-04-01 16:20:45',
    3 => '1817',
    4 => 'nxlog',
    5 => '2328.02 Hours',
  ),
)

CodePudding user response:

Please have a look at bellow snippet

echo '<pre>';
function ShortFunction($new,$old){
    return floatval($old[5]) <=> floatval($new[5]);
}
$new_array = usort($unresponsives,'ShortFunction');
print_r($unresponsives);
  • Related