在日常PHP 編程中,我們經常需要對字符串數組進行排序,但默認的字典序排序( sort 、 usort等)並不能很好地處理帶有數字的字符串。比如img1.png , img2.png , img10.png這樣的文件名,如果用普通的字符串比較,排序結果會是img1.png , img10.png , img2.png ,顯然不符合人類的自然排序習慣。
為了實現“自然排序”,PHP 提供了strnatcmp和strnatcasecmp函數,分別對應區分大小寫和不區分大小寫的自然排序。
另外,當我們對數組排序時,常常還需要對數組中的每個元素統一格式化,比如全部轉小寫或去掉多餘空格,這時候可以用array_map來實現。
本文將介紹如何將這兩個工具結合起來,對數組中的字符串進行統一格式化後,再進行自然排序。
1??準備數據數組<br> 我們以一組文件名為例
$files = ['Img10.png', 'img2.png', 'IMG1.png', 'img20.png', 'img11.png'];
2??使用array_map 格式化元素<br> 假設我們想把它們全部轉為小寫
$formattedFiles = array_map('strtolower', $files);
如果要更複雜的處理(比如去空格、統一擴展名),可以寫成匿名函數:
$formattedFiles = array_map(function($item) {
return strtolower(trim($item));
}, $files);
3??自定義排序函數
PHP 的usort允許我們用自定義函數排序:
usort($formattedFiles, 'strnatcasecmp');
注意: strnatcasecmp是一個比較函數,而不是直接用於排序的函數。
<?php
$files = ['Img10.png', 'img2.png', 'IMG1.png', 'img20.png', 'img11.png'];
// 第一步:統一格式(轉小寫 + 去空格)
$formattedFiles = array_map(function($item) {
return strtolower(trim($item));
}, $files);
// 第二步:自然排序(不區分大小寫)
usort($formattedFiles, 'strnatcasecmp');
// 輸出結果
foreach ($formattedFiles as $file) {
echo $file . "\n";
}
?>
運行結果:
img1.png
img2.png
img10.png
img11.png
img20.png
假設我們處理的是一組URL:
$urls = [
'https://gitbox.net/File10.html',
'https://gitbox.net/file2.html',
'https://gitbox.net/FILE1.html',
'https://gitbox.net/file20.html',
'https://gitbox.net/file11.html',
];
我們想按文件名部分排序,可以先提取文件名,再排序:
<?php
$urls = [
'https://gitbox.net/File10.html',
'https://gitbox.net/file2.html',
'https://gitbox.net/FILE1.html',
'https://gitbox.net/file20.html',
'https://gitbox.net/file11.html',
];
// 提取文件名部分並綁定到 URL
$mapped = array_map(function($url) {
$parts = parse_url($url);
$file = basename($parts['path']);
return ['url' => $url, 'file' => strtolower($file)];
}, $urls);
// 按文件名自然排序
usort($mapped, function($a, $b) {
return strnatcasecmp($a['file'], $b['file']);
});
// 輸出排序後的 URL
foreach ($mapped as $item) {
echo $item['url'] . "\n";
}
?>
輸出:
https://gitbox.net/FILE1.html
https://gitbox.net/file2.html
https://gitbox.net/File10.html
https://gitbox.net/file11.html
https://gitbox.net/file20.html