【问题标题】:PHP sorting multidimensional array, can only sort one columnPHP排序多维数组,只能排序一列
【发布时间】:2012-03-11 06:35:10
【问题描述】:

首先,是的,这是一个重复的问题,在这里被问了 100 次,我已经阅读了许多帖子,但是给出的示例对我来说并不是 100% 有效,我无法弄清楚我哪里错了。

我想通过“距离”键对这样的数组进行排序,并且我希望将排序“扩展”到整个数组中,以便对数组中的所有键重新排序。本质上,就像您对电子表格中的一列进行排序并将排序扩展到所有列一样。

这是示例数组:

$locations = array ( 
[phone] => Array ( 
    [0] => 555-123-1234 
    [1] => 555-456-4321 
    [2] => 555-789-1122 
    [3] => 555-321-1111 ) 
[address] => Array ( 
    [0] => 123 Main Street BigCity, NY 12345
    [1] => 456 Maple Street Somewhere, UT 87654
    [2] => 999 1st Ave MyTown, VA 23456
    [3] => 321 2nd Ave MyTown, VA 23456 ) 
[distance] => Array ( 
    [0] => 24.56
    [1] => 13.05
    [2] => 23.99
    [3] => 1.75 ) 
[name] => Array ( 
    [0] => First Location
    [1] => Second Location
    [2] => Third Location
    [3] => Fourth Location ) 
)

我正在尝试按“距离”对数组进行排序,并且我尝试同时使用 array_multisort() 函数和 usort() 函数......但只有“multisort”通过排序给我提供了几乎可用的结果只有距离,而不是根据距离对整个数组进行排序。

我的功能:

array_multisort($locations['distance'], SORT_NUMERIC);

然后我运行一个“for”循环来遍历数组并按键吐出值。结果是距离已排序,但位置名称、地址等未重新排序。

我在这里错过了什么??

谢谢!!

【问题讨论】:

    标签: php multidimensional-array sorting


    【解决方案1】:

    您的数组是按列排列的,而array_multisort() 以这种方式使用时会要求它按行排列。

    如果你这样做,它应该是你会得到的结构:

    $rows = array();
    while ($row = $result->fetch_assoc()) $rows[] = $row;
    

    ...带有 MySQLi 结果对象。

    您可以很容易地将现有数组重新格式化为这种结构:

    $locationsAsRows = array();
    for ($i = 0; isset($locations['phone'][$i]); $i++) {
      $locationsAsRows[$i] = array (
        'phone' => $locations['phone'][$i],
        'address' => $locations['address'][$i],
        'distance' => $locations['distance'][$i],
        'name' => $locations['name'][$i]
      );
    }
    var_dump($locationsAsRows);
    

    现在,当你这样做时:

    array_multisort($locations['distance'], SORT_NUMERIC, $locationsAsRows);
    var_dump($locationsAsRows);
    

    ...可以看到数据已经排序了。请注意,我不仅传递了您想要排序的列数据,而且还传递了整个“行格式化”$locationsAsRows 数组作为最后一个参数。这是通过引用传递的,所以$locationsAsRows 本身就是你调用array_multisort() 之后的排序数据。

    现在假设两个distance 值相同 - 我们需要提供第二个优先搜索列。所以接下来,我们可以按address 排序,我们可以这样做:

    array_multisort($locations['distance'], SORT_NUMERIC, $locations['address'], SORT_ASC, $locationsAsRows);
    

    See it working 和它一起玩...

    【讨论】:

    • 感谢您的精彩解释和示例!我想我不理解的部分内容是这些函数如何查看数组。但是,在使用您的示例时,我必须按行对我想要匹配的所有列进行排序。我不确定为什么会这样,但如果我在多排序函数中添加所有行,它就会起作用。关于为什么会这样的任何想法?
    • array_multisort() 可以以多种方式使用,但使用此选项的行为大致类似于 SQL 查询中的 order by 子句。而在 SQL 中,您总是在处理行。您必须传递要按(列)排序的数据集,以便它知道如何对数据进行排序,然后将整个数据集作为最后一个参数传递,以便可以根据这些规则对其进行排序。所以就像SELECT phone, address, distance, name FROM locations ORDER BY distance
    • 这相当于SELECT phone, address, distance, name FROM locations ORDER BY distance, address, name, phone - 在完整数据集$locationsAsRows 之前每增加一对$col, SORT_CONST 值就像ORDER BY 子句的另一个级别。因此,$locations['phone'], SORT_ASC 可能永远无法到达,除非两条记录具有完全相同的 distanceaddressname 值。
    • 当你把它放在 SQL 中这样说时,这是完全有道理的,但我必须这样做才能将所有行排序在一起:array_multisort($locations['distance'], SORT_NUMERIC, $locations['address'], SORT_ASC, $locations['name'], SORT_ASC, $locations['phone'], SORT_ASC, $locationsAsRows); ....否则它只订购了一个列。
    【解决方案2】:
    array_multisort($locations['distance'],$locations['name'],$locations['address'],$locations['phone'],SORT_NUMERIC);
    

    也许这可以完成这项工作?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多