如何在PHP版本5.4中对多维数组排序-使用键?
我问了一个问题,得到了极好的回答 但后来我不得不对数组数据做了一个更改,它破坏了排序算法,我不知道为什么 在上一个问题中,我的数组如下所示:如何在PHP版本5.4中对多维数组排序-使用键?,php,arrays,sorting,Php,Arrays,Sorting,我问了一个问题,得到了极好的回答 但后来我不得不对数组数据做了一个更改,它破坏了排序算法,我不知道为什么 在上一个问题中,我的数组如下所示: Array ( [0] => Array ( [0] => Game [1] => Date [2] => Site [3] => Address [4] => FirstNam
Array
(
[0] => Array
(
[0] => Game
[1] => Date
[2] => Site
[3] => Address
[4] => FirstName
[5] => LastName
[6] => Email
[7] => Phone
)
[1] => Array
(
[0] => B-Dry @ Blue Wave DH
[1] => 7/9/2019 13:00
[2] => Blue Wave Dover City Park
[3] => Dover
[4] => John
[5] => Doe
[6] => john.doe@perrylocal.org
[7] => (555) 555-4797
)
[2] => Array
(
[0] => B-Dry @ Blue Wave DH
[1] => 7/9/2019 13:00
[2] => Blue Wave Dover City Park
[3] => Dover
[4] => Frank
[5] => Sinatra
[6] => frank@sinatra.com
[7] => (555) 685-5555
)
[3] => Array
(
[0] => B-Dry @ Gnaden
[1] => 6/7/2019 18:00
[2] => Gnaden Indian Valley HS
[3] => Gnadenhutten
[4] => Jimmy
[5] => Dean
[6] => jimmy@dean.org
[7] => (330) 555-5555
)
[...many more...]
)
应用AymDev的以下排序算法对其进行了出色的排序:
$labelsRow = array_shift($cleanSheetArray);
$cleanSheetArray = array_map(
function ($cleanRowArray)
{
$cleanRowArray[1] = DateTime::createFromFormat('d/m/Y H:i', $cleanRowArray[1]);
return $cleanRowArray;
}
, $cleanSheetArray);
SortSheet($cleanSheetArray, 3);
function SortSheet(&$arr, $max_index = false, $index = 0) { // $index represents the number of columns to sort on, in order from the first column
function mult_usort_callback($a, $b, $max_index, $index) {
$max_index = $max_index ?: (count($a) - 1);
// Recursively sort till the max index
if ($a[$index] == $b[$index]) {
if ($index < $max_index) {
return mult_usort_callback($a, $b, $max_index, ($index + 1));
} else {
return 0;
}
}
return $a[$index] > $b[$index] ? 1 : -1;
};
usort($arr, create_function('$a, $b', 'return mult_usort_callback($a, $b, ' . $max_index . ', ' . $index . ');'));
}
注意,我将键从索引器更改为列名。这对我以后处理逻辑有很大帮助。在更改数据/键的同时,我尝试更改日期对象化:
$cleanSheetArray = array_map(function ($cleanRowArray) {
$cleanRowArray['Date'] = DateTime::createFromFormat('d/m/Y H:i', $cleanRowArray['Date']);
return $cleanRowArray;
}, $cleanSheetArray);
从将字符串日期转换为日期对象的角度来看,这似乎是可行的。但它打破了分类。通过查看新数组的3个元素,您可以看到坏排序的证据。请注意,阵列段151和153应该是连续的,因为游戏、日期和地点是相同的。152的值与151和152的值不同。游戏和日期是一样的,但地点不同。在以前使用索引键而不是命名键的数组结构中,排序是正确的
我怀疑我需要对SortSheet函数进行某种更改,但我不知道它是什么
重要提示:密钥名称序列将始终相同。换句话说,关键序列总是游戏,然后是日期,然后是站点,等等,这样序列总是可以被计算的
有什么想法吗?使用之前的数字顺序数组,快速修复方法可能是:
// Save the keys
$keys = array_shift($data);
/* here, do the sorting ... */
// Then apply the keys to your ordered array
$data = array_map(function ($item) {
global $keys;
return array_combine($keys, $item);
}, $data);
但让我们更新我的:
使用和输出:
mult_usort_assoc($data, 'Site');
echo '<pre>' . print_r($data, true) . '</pre>';
此答案中使用的函数:
将日期转换为unix时间戳,比较运算符将再次工作。到目前为止,PHP不知道如何比较两个日期对象,因此排序失败。谢谢MonkeyZeus,但我对你的建议感到困惑,因为只要我在数组中使用数字索引器而不是命名键,比较两个日期对象就可以完美地工作。我不同意@MonkeyZeus see,您可以像比较数字一样比较DateTime对象。我认为这与_u-toString方法有关,但不确定,从未尝试过。这非常有效。再一次,艾姆德夫,非常感谢你的帮助。不客气,这再一次很有趣。不管怎样,我想到了一个改进的关联数组函数,你给了我这样做的可能性!
function mult_usort_assoc(&$arr, $max_index = false, $index = false) {
function mult_usort_callback($a, $b, $max_index, $index) {
$max_index = $max_index ?: key(end($a)); // If not provided, takes last key
$index = $index ?: array_keys($a)[0]; // If not provided, takes first key
// When data are equal, sort by next key only if not after the $max_index
if ($a[$index] == $b[$index]) {
$next = array_keys($a)[array_search($index,array_keys($a))+1];
if ($index !== $max_index && !is_null($next)) {
return mult_usort_callback($a, $b, $max_index, $next);
} else {
return 0;
}
}
return $a[$index] > $b[$index] ? 1 : -1;
}
/* This part have been improved as we shouldn't use create_function()
This function is now usable in PHP 7.2 */
usort($arr, function ($a, $b) use ($max_index, $index) {
return mult_usort_callback($a, $b, $max_index, $index);
});
}
mult_usort_assoc($data, 'Site');
echo '<pre>' . print_r($data, true) . '</pre>';