按列中的值对多维数组进行排序

15

我有这个数组

Array
(
    [0] => Array
        (
            [brand] => blah blah
            [location] => blah blah
            [address] => blah blah
            [city] => blah blah
            [state] => CA
            [zip] => 90210
            [country] => USA
            [phone] => 555-1212
            [long] => -111
            [lat] => 34
            [distance] => 3.08
        )
    [1] => Array
        (
            [brand] => blah blah
            [location] => blah blah
            [address] => blah blah
            [city] => blah blah
            [state] => CA
            [zip] => 90210
            [country] => USA
            [phone] => 555-1212
            [long] => -111
            [lat] => 34
            [distance] => 5
        )
.
.
.

}

我希望能够按距离对哈希内的数组进行排序。


array_multisort是反向的:它对列数组进行排序。(实际上,它对表示列的多个独立数组进行排序。)这几乎永远不是你想要的:要么转置你的数组,要么使用像usort这样有用的东西。 - aib
6个回答

24

你需要先提取所有距离,然后将距离和数据一起传递给函数。就像在array_multisort文档的示例3中所示。

foreach ($data as $key => $row) {
    $distance[$key] = $row['distance'];
}

array_multisort($distance, SORT_ASC, $data);

假设您希望首先得到最短的距离,否则将 SORT_ASC 更改为 SORT_DESC


16
如果您想避免循环,可以使用array_column函数来实现您的目标。 例如,您想按照距离对下面的数组进行排序。
$arr = array( 
  0 => array( 'lat' => 34, 'distance' => 332.08 ),
  1 => array( 'lat' => 34, 'distance' => 5 ),
  2 => array( 'lat' => 34, 'distance' => 34 )
);
使用下面的一行代码,可以按距离对数组进行排序。
array_multisort( array_column( $arr, 'distance' ), SORT_ASC, SORT_NUMERIC, $arr );

现在,$arr 中包含按照 距离 排序后的数组。


4
调用usort()比调用array_multisort()的优点在于,你不需要预先迭代输入数组以生成列数据的数组。
以下一行代码将使用PHP7.4的箭头函数语法与PHP7的“太空船运算符” / “三向比较运算符”,根据距离列值对输入数组(通过引用)进行排序。
$a置于<=> 的左侧,将$b置于右侧,则使用升序。要实现降序排序,请写成$b ['distance'] <=> $a['distance']
代码:
usort($array, fn($a, $b) => $a['distance'] <=> $b['distance']);

var_export($array);

为了在排序时打破平局,可以通过值的数组声明多个要排序的值。

以下将按照以下方式进行排序:

  1. 先按距离升序排序,然后
  2. 按国家降序排序,然后
  3. 再按州的升序排序,最后
  4. 按城市的升序排序

代码:

usort(
    $array,
    fn($a, $b) =>
        [$a['distance'], $b['country'], $a['state'], $a['city']]
        <=>
        [$b['distance'], $a['country'], $b['state'], $b['city']]
);

2

您可以使用usort函数;

function cmpDistance($a, $b) {
    return ($a['distance'] - $b['distance']);
}

usort($array, "cmpDistance");

为什么我会收到“致命错误:无法重新声明cmp()”?我感到困惑。 - dst11
@dst11,只需将函数名称更改为其他名称,您可能已经在某个地方定义了它。 - Czechnology
奇怪,它几乎排好序了...哈哈哈,由于某些原因,一些条目仍然未排序。这可能与距离是双精度类型有关吗?我不理解这个。 - dst11
是的,在排序之前距离分别为:1.95、2.31、4.04、4.9、1.58、404等等。之后我得到了0.42、1.24、2.27、1.57等等……这里可能出了什么问题? - dst11
@dst11,我认为这不是正确的方法,因为(int)1.1 == (int)1.9(强制转换只会截断小数部分),这意味着具有这种距离的条目将被视为具有相同的距离。请改用(float)floatval() - Czechnology
显示剩余3条评论

1

这段代码使用array_multisort()函数来对多维数组进行排序。

  $param_dt = array();
  foreach ($data_set as $key => $row) {
     if(isset($row['params']['priority']))
     {
       $param_dt[$key] = $row['params']['priority'];
     }
     else
     {
        $param_dt[$key] = -2; // if priority key is not set for this array - it first out
     }
    }

  array_multisort($param_dt, SORT_ASC,SORT_NUMERIC, $data_set); 

现在,$data_set 包含已排序的元素列表。

1
我们有一行数组,但是array_multisort()需要一列数组,所以我们使用下面的代码获取列,然后进行排序。
// as of PHP 5.5.0 you can use array_column() instead of the above code
$brand= array_column($data, 'brand');
$city= array_column($data, 'city');

// Sort the data with volume descending, edition ascending
// Add $data as the last parameter, to sort by the common key
array_multisort($brand, SORT_DESC, $city, SORT_ASC, $data);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接