【问题标题】:Properly getting the sorting order of this array in PHP在 PHP 中正确获取此数组的排序顺序
【发布时间】:2018-10-08 04:19:59
【问题描述】:

我有一个二维数组,其中的值...

9999999999999999  3201  4584  4821  1628  1218  1786  4738  4897
3122  9999999999999999  1400  1638  1797  2756  3323  5310  5472
4523  1400  9999999999999999  237 3198  4156  4723  6711  6872
4760  1638  237 9999999999999999  3435  4394  4961  6948  7110
1324  1846  3247  3485  9999999999999999  958 1525  3931  4093
932 2854  4273  4510  1002  9999999999999999  567 4873  5034
1499  3422  4840  5078  1569  567 9999999999999999  5440  5602
5061  5359  6760  6998  4019  4959  5526  9999999999999999  161
5233  5531  6931  7169  4190  5130  5697  171 9999999999999999

这是代码中的相同数组:

array:9 [
  0 => array:9 [
    0 => 9999999999999999
    1 => 3122
    2 => 4523
    3 => 4760
    4 => 1324
    5 => 932
    6 => 1499
    7 => 5061
    8 => 5233
  ]
  1 => array:9 [
    0 => 3201
    1 => 9999999999999999
    2 => 1400
    3 => 1638
    4 => 1846
    5 => 2854
    6 => 3422
    7 => 5359
    8 => 5531
  ]
  2 => array:9 [
    0 => 4584
    1 => 1400
    2 => 9999999999999999
    3 => 237
    4 => 3247
    5 => 4273
    6 => 4840
    7 => 6760
    8 => 6931
  ]
  3 => array:9 [
    0 => 4821
    1 => 1638
    2 => 237
    3 => 9999999999999999
    4 => 3485
    5 => 4510
    6 => 5078
    7 => 6998
    8 => 7169
  ]
  4 => array:9 [
    0 => 1628
    1 => 1797
    2 => 3198
    3 => 3435
    4 => 9999999999999999
    5 => 1002
    6 => 1569
    7 => 4019
    8 => 4190
  ]
  5 => array:9 [
    0 => 1218
    1 => 2756
    2 => 4156
    3 => 4394
    4 => 958
    5 => 9999999999999999
    6 => 567
    7 => 4959
    8 => 5130
  ]
  6 => array:9 [
    0 => 1786
    1 => 3323
    2 => 4723
    3 => 4961
    4 => 1525
    5 => 567
    6 => 9999999999999999
    7 => 5526
    8 => 5697
  ]
  7 => array:9 [
    0 => 4738
    1 => 5310
    2 => 6711
    3 => 6948
    4 => 3931
    5 => 4873
    6 => 5440
    7 => 9999999999999999
    8 => 171
  ]
  8 => array:9 [
    0 => 4897
    1 => 5472
    2 => 6872
    3 => 7110
    4 => 4093
    5 => 5034
    6 => 5602
    7 => 161
    8 => 9999999999999999
  ]
]

我想要实现的是根据最接近的方式找到该数组的排序顺序。每行包含一个地方到另一个地方的距离。

换句话说,数组看起来像:

        China    India    USA    Japan
China     0        50     4000    2000
India     50       0      4100    2100
USA      4050     4120      2     3000
Japan    2010     1950    2997     0

如您所见,self 的值为 0,有时它是一个小数字,例如 2-10(不太确定),因为 Google 距离矩阵 API 有时也会为相同的起点和终点返回较大的值,这就是我替换的原因在我上面的原始数组的整个对角线上,它是 9999999999999999。

目标是根据距离进行排序。第一个条目是起点,因此在上面的假设数组的情况下,它将是: [0 1 3 2] 即从中国到印度,然后印度到日本,日本到美国。我的目标是最终使用 array_multisort 来对带有地名的键进行排序,以便正确排序。

我想出的代码没有像我希望的那样工作:

$order = [0];
$i = 0;
$nextItemToProcessIndex = 0;
foreach($tempMatrix as $key => $entry) {
    $tempMatrix[$key][$key] = PHP_INT_MAX;
}
while(!empty($tempMatrix)) {
    $closestItemIndex = array_search(min($tempMatrix[$nextItemToProcessIndex]), $tempMatrix[$nextItemToProcessIndex]);
    array_push($order, $closestItemIndex);
    $this->pull_item($tempMatrix, $nextItemToProcessIndex);
    $nextItemToProcessIndex = $closestItemIndex - 1;
    $i++;
}
dd($order);
...
...
public function pull_item(&$array, $offset) {
    array_walk($array, function (&$v) use ($offset) {
        array_splice($v, $offset, 1);
    });
    $row = array_splice($array, $offset, 1);
    return $row;
}

【问题讨论】:

  • 排序后的数组是什么样子的?
  • 我还没有完全计算出原始数组。前几个值是 [0, 5, 6 并且继续]。对于示例数组(中国、印度、美国、日本一号),它是描述中提到的 [0 1 3 2]。
  • 这是排序顺序(手动完成)= [0, 5, 6, 4, 1, 2, 3, 7, 8]。
  • 您无法对矩阵进行排序 - 除非您认为列或行标签会因单元格而异。或者您可以尝试对国家/地区对列表进行排序

标签: php arrays sorting multidimensional-array google-distancematrix-api


【解决方案1】:

如果您可以更改矩阵列标签 - 您可以像这样进行排序:

$dist = [
    "China" => ['China' =>    0, 'India' =>   50,  'USA' => 4000, 'Japan' => 2000],
    "India" => ['China' =>   50, 'India' =>    0,  'USA' => 4100, 'Japan' => 2100],
    "USA  " => ['China' => 4050, 'India' => 4120,  'USA' =>    2, 'Japan' => 3000],
    "Japan" => ['China' => 2010, 'India' => 1950,  'USA' => 2997, 'Japan' =>    0]
];

// sort columns by distance
foreach ($dist as $key => $value) {
    asort($dist[$key]);
}

// display distances matrix
foreach ($dist as $row_c => $data) {
    $row1 = "\t";
    $row2 = $row_c . " : ";
    foreach ($data as $col_c => $col_dist) {
        $row1 .= $col_c . "\t";
        $row2 .= $col_dist . "\t";
    }
    echo "{$row1}\n{$row2}\n\n";
}

输出:

中国 印度 日本 美国 中国:0 50 2000 4000 印度 中国 日本 美国 印度:0 50 2100 4100 美国 日本 中国 印度 美国:2 3000 4050 4120 日本 印度 中国 美国 日本 : 0 1950 2010 2997

【讨论】:

  • 感谢您写这篇文章,但我并不是要对矩阵进行排序以获得递增的距离值。请阅读说明,您会发现我正在尝试找到从一个地方到另一个地方的最佳顺序。
  • 你的描述不是很清楚。如果说“最佳顺序”-您想到了两个国家之间的最短路径(或fromto之间的最少国家/地区)-那么您需要类似A*的东西-寻路算法(排序不会帮助你)。否则-定义术语“最佳顺序”-您发布的帖子根本没有帮助
【解决方案2】:

我能够自己想出一个解决方案。如果其他人遇到同样的问题,请在此处发布:

$nextItemToProcess = 0;
$order = [0];

foreach(range(0, count($tempMatrix) - 2) as $i) {
    if(count(array_diff_key($tempMatrix[$nextItemToProcess], $order)) == 1) {
      $order = array_merge($order, array_diff(range(0, count($tempMatrix)-1), $order));
      break;
    }

    $diffArray = array_diff_key($tempMatrix[$nextItemToProcess], array_flip($order));
    $closestItemIndex = array_search(min($diffArray), $tempMatrix[$nextItemToProcess]);
    array_push($order, $closestItemIndex);
    $nextItemToProcess = $closestItemIndex;
}

$ascOrigins = [];
foreach($order as $i) {
    array_push($ascOrigins, $arrOrigins[$i]);
}

ascOrigins 是按位置距离升序排列的数组。我以为我可以使用 php 的 array_multisort 但它没有用,因为我在这里根据 order 的值对 arr 的键进行排序。 (我知道 array_flip 可以做到这一点,但这很好用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-13
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多