在 PHP 中正确获取此数组的排序顺序
Properly getting the sorting order of this array in PHP
我有一个二维数组,其中的值...
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 有时 returns 对于相同的起点和终点也有很大的价值,这就是为什么我将它替换为 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;
}
如果您可以更改矩阵列标签 - 您可以这样进行排序:
$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";
}
输出:
China India Japan USA
China : 0 50 2000 4000
India China Japan USA
India : 0 50 2100 4100
USA Japan China India
USA : 2 3000 4050 4120
Japan India China USA
Japan : 0 1950 2010 2997
我自己找到了解决方案。如果其他人遇到同样的问题,请在此处发布:
$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 但它没有用,因为在这里我根据顺序值对 arr 的键进行排序。 (我知道 array_flip 可以解决这个问题,但这很好用)。
我有一个二维数组,其中的值...
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 有时 returns 对于相同的起点和终点也有很大的价值,这就是为什么我将它替换为 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;
}
如果您可以更改矩阵列标签 - 您可以这样进行排序:
$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";
}
输出:
China India Japan USA China : 0 50 2000 4000 India China Japan USA India : 0 50 2100 4100 USA Japan China India USA : 2 3000 4050 4120 Japan India China USA Japan : 0 1950 2010 2997
我自己找到了解决方案。如果其他人遇到同样的问题,请在此处发布:
$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 但它没有用,因为在这里我根据顺序值对 arr 的键进行排序。 (我知道 array_flip 可以解决这个问题,但这很好用)。