PHP 对非关联数组的数组进行排序,但开头有字符串值

问题描述 投票:0回答:3
 $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"
    ]]

这是我的数组中的一个示例。我想按第五个元素(小时)按降序对内部数组进行排序。我可以使用 usort 来实现此目的,但在数组中还有一些数组以字符串“Undefine”作为第五个值。下面的例子:

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

目前排序完成后它们列在数组的底部。相反,我希望它们列在数组的开头。因此,首先是未定义的数组,然后是其余的按降序排列。我怎样才能实现这个目标?

下面是我使用的usort函数:

usort($unresponsives, function ($unresponsive1, $unresponsive2) {
            return floatval($unresponsive2[5]) <=> floatval($unresponsive1[5]);
        });
php arrays sorting usort
3个回答
0
投票

array_multisort
方法 - 示例 https://3v4l.org/SuJQX

采用稍微复杂的方法,可以根据需要对排序进行细粒度控制。使用

array_column
检索小时数。在小时上使用
array_keys
来确定过滤后的值位置,并迭代这些位置以将它们分配为数值。然后
array_multisort
可以与所需的标志一起使用来对结果数组进行排序。

$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);

结果

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',
  ),
)

数字升序排序

要将排序顺序更改为

SORT_ASC
,请将
PHP_INT_MAX
替换为
PHP_INT_MIN
,具体取决于您希望过滤后的值位于数组中的位置。

$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);

结果

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',
  ),
)

usort
方法 - 示例 https://3v4l.org/Uoml6

通过在条件中操作所需过滤值的比较值,可以将过滤值分配为数值的相同方法应用于

usort
,该方法仅用于对数组进行排序。

降序排列

function compd($a, $b)
{
    /*
    # Condensed Syntax
    return ('Undefined' === $b[5] ? PHP_INT_MAX : floatval($b[5])) <=> ('Undefined' === $a[5] ? PHP_INT_MAX : floatval($a[5]));
    */

     $v1 = $a[5];
     $v2 = $b[5];
     if ('Undefined' === $v1) {
         $v1 = PHP_INT_MAX;
     }
     if ('Undefined' === $v2) {
         $v2 = PHP_INT_MAX;
     }

     return floatval($v2) <=> floatval($v1);
}

usort($unresponsives, 'compd');

升序

array_multisort
方法一样,通过将
PHP_INT_MAX
PHP_INT_MIN
交换来更改排序顺序,还可以将
$b[5] <=> $a[5]
$a[5] <=> $b[5]
比较交换以按升序对值进行排序。

function compa($a, $b) 
{
    /*
    # Condensed Syntax
    return ('Undefined' === $a[5] ? PHP_INT_MIN : floatval($a[5])) <=> ('Undefined' === $b[5] ? PHP_INT_MIN : floatval($b[5]));
    */

     $v1 = $a[5];
     $v2 = $b[5];
     if ('Undefined' === $v1) {
         $v1 = PHP_INT_MIN;
     }
     if ('Undefined' === $v2) {
         $v2 = PHP_INT_MIN;
     }

     return floatval($v1) <=> floatval($v2);
}

usort($unresponsives, 'compa');

0
投票

我建议分两步。

  1. 用准备比较的数值填充数组。
  2. 调用
    array_multisort()
    进行 DESC 方向比较。

代码:(演示

array_multisort(
    array_map(
        fn($a) => sscanf($a[5], '%f')[0] ?? PHP_INT_MIN,
        $unresponsives
    ),
    SORT_DESC,
    $unresponsives
);
var_export($unresponsives);

这也可以在完全不迭代函数调用的情况下执行,以获得更高的效率。

第一条规则在

Undefined
评估之前检查
true
值和顺序
false
评估。第二条规则仅在需要决胜局时适用 - 在这种情况下,将比较浮点值的 DESC 排序方向。

代码:(演示

usort(
    $unresponsives,
    fn($a, $b) => 
        [$b[5] === 'Undefined', (float) $b[5]]
        <=>
        [$a[5] === 'Undefined', (float) $a[5]]
);
var_export($unresponsives);

可以在此处找到类似的方法。


-2
投票

请看下面的片段

echo '<pre>';
function ShortFunction($new,$old){
    return floatval($old[5]) <=> floatval($new[5]);
}
$new_array = usort($unresponsives,'ShortFunction');
print_r($unresponsives);
© www.soinside.com 2019 - 2024. All rights reserved.