我需要按"R"后面的数字重新排序数组中的元素,然后是第一部分。
我有一个包含以下元素的数组。
215/75R17.5
235/75R17.5
8.25R16
7.00R16
11R22.5
7.50R16
所以到这个:
7.00R16
7.50R16
8.25R16
11R22.5
215/75R17.5
235/75R17.5
首先,
这显然是一个自定义比较; 其首选函数是 usort
,它接受自定义比较作为参数。
自定义比较函数如下所示:
function customCompare($x, $y) {
$x = explode('R', $x);
$y = explode('R', $y);
if ($x[1] != $y[1]) return $x[1] < $y[1] ? -1 : 1;
return strnatcmp($x[0], $y[0]);
}
看到它的实际效果。
工作原理
首先,我们在字符R
上拆分每个输入字符串,从'8.25R16'
这样的字符串中生成一个数组,如['8.25', '16']
。在每个数组中,第二个元素是直径(第一个排序标准),第一个元素是宽度(第二个标准)。
如果直径不同,那么我们立即根据此做出判断。
如果直径相等,那么我们使用strnatcmp
来比较宽度 - 这样宽度 100 大于宽度 20(愚蠢的 ASCII 比较会产生相反的结果)。
无论你决定如何隔离R
后面的子字符串,你都应该尽量减少函数调用的次数。
将array_multisort()
与隔离技术的映射调用一起使用将比usort()
方法执行得更好,因为usort()
将在同一值上多次执行隔离技术。
在下面的代码段中,我在隔离时不会删除R
,因此我使用自然排序来正确比较数字子字符串。 如果您不熟悉strpbrk()
请参阅此答案以进行演示。
代码:(演示)
$array = [
'215/75R17.5',
'235/75R17.5',
'8.25R16',
'7.00R16',
'11R22.5',
'7.50R16'
];
array_multisort(array_map(fn($v) => strpbrk($v, 'R'), $array), SORT_NATURAL, $array);
var_export($array);
<小时 />纯粹隔离数值的方法不需要自然排序。(演示)
array_multisort(array_map(fn($v) => sscanf($v, '%*[^R]R%f')[0], $array), $array);
var_export($array);