如何在数组中排序文件名,如在windows文件夹中,按名称?代码和数组是这样的:
$arr = array('php__01.png','php__02.png','php__03.png','php_2_01.png','php_2_02.png','php_10_01.png','php_10_02.png','php_9_02.png','php_9_01.png','php_9_03.png');
<?php
$arr = array('php__01.png','php__02.png','php__03.png','php_2_01.png','php_2_02.png','php_10_01.png','php_10_02.png','php_9_02.png','php_9_01.png','php_9_03.png');
function cmp($a, $b) {
$a_temp = str_replace('_', '', $a);
$b_temp = str_replace('_', '', $b);
return strcmp($a_temp,$b_temp);
}
usort($arr, "cmp");
?>
导出如下:
array(10) {
[0]=>
string(11) "php__01.png"
[1]=>
string(11) "php__02.png"
[2]=>
string(11) "php__03.png"
[3]=>
string(13) "php_10_01.png"
[4]=>
string(13) "php_10_02.png"
[5]=>
string(12) "php_2_01.png"
[6]=>
string(12) "php_2_02.png"
[7]=>
string(12) "php_9_01.png"
[8]=>
string(12) "php_9_02.png"
[9]=>
string(12) "php_9_03.png"
}
我想这样排序:
array(10) {
[0]=>
string(10) "py__01.png"
[1]=>
string(10) "py__02.png"
[2]=>
string(10) "py__03.png"
[3]=>
string(11) "py_2_01.png"
[4]=>
string(11) "py_2_02.png"
[5]=>
string(11) "py_9_01.png"
[6]=>
string(11) "py_9_02.png"
[7]=>
string(11) "py_9_03.png"
[8]=>
string(12) "py_10_01.png"
[9]=>
string(12) "py_10_02.png"
}
解决方案如下:
<?php
$arr = array('php__01.png','php__02.png','php__03.png','php_2_01.png','php_2_02.png','php_10_01.png','php_10_02.png','php_9_02.png','php_9_01.png','php_9_03.png');
function reduce($a) {
$a = str_replace('_', '-', $a);
$a = preg_replace('#([0-9]+)#e', 'sprintf("%02d", "\1")', $a);
return $a;
}
function cmp($a, $b) {
$a_temp = reduce($a);
$b_temp = reduce($b);
return strcmp($a_temp,$b_temp);
}
usort($arr, "cmp");
print_r($arr);
?>
http://ideone.com/Yt6jpQ 您需要将"_"替换为"-",因为在排序数字时,"-"字符首先出现。
你还需要用前导零填充数字,这就是preg_match和sprintf的原因。
输出:Array
(
[0] => php__01.png
[1] => php__02.png
[2] => php__03.png
[3] => php_2_01.png
[4] => php_2_02.png
[5] => php_9_01.png
[6] => php_9_02.png
[7] => php_9_03.png
[8] => php_10_01.png
[9] => php_10_02.png
)
您可以使用ussort;在本例中,按文件名的每个元素依次排序
$cb = function($valueA, $valueB) {
$vA = explode('_', $valueA);
$vB = explode('_', $valueB);
$element = 0;
do {
$x = (int) $vA[$element] - (int) $vB[$element++];
} while ($x == 0);
return $x;
};
usort($arr, $cb);
这是一个更通用的方法,不会在"_"
上分裂。
$arr = array('php__01.png','php__02.png','php__03.png','php_2_01.png','php_2_02.png','php_10_01.png','php_10_02.png','php_9_02.png','php_9_01.png','php_9_03.png');
$wincmp = function ($a, $b) {
$a = str_replace('_', '', $a);
$b = str_replace('_', '', $b);
$a_arr = preg_split("#([0-9]+)#", $a, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$b_arr = preg_split("#([0-9]+)#", $b, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$a_arr_len = count($a_arr);
$b_arr_len = count($b_arr);
$min_len = min($a_arr_len, $b_arr_len);
for($i=0; $i<$min_len; $i++)
{
if (is_numeric($a_arr[$i]) && is_numeric($b_arr[$i]))
$cmp = gmp_sign((int) $a_arr[$i] - (int) $b_arr[$i]);
else
$cmp = strcmp($a_arr[$i],$b_arr[$i]);
if($cmp != 0)
return $cmp;
}
if($a_arr_len < $b_arr_len)
return -1;
elseif($a_arr_len > $b_arr_len)
return 1;
return 0;
};
usort($arr, $wincmp);
print_r($arr);