毎日のPHPプログラミングでは、多くの場合、文字列配列をソートする必要がありますが、デフォルトの辞書ソート(並べ替え、 USORTなど)では、数字の文字列をうまく処理しません。たとえば、 IMG1.png 、 IMG2.png 、 IMG10.pngなどのファイル名が通常の文字列と比較される場合、ソート結果はIMG1.png 、 IMG10.png 、 IMG2.pngになります。
「自然な並べ替え」を達成するために、PHPはそれぞれSTRNATCMPおよびSTRNATCASECMP機能を提供します。
さらに、配列をソートするとき、すべての小文字を回す、不必要なスペースの削除など、アレイの各要素を均一にフォーマットする必要があります。現時点では、 array_mapを使用してそれを実現できます。
この記事では、これら2つのツールを組み合わせ、配列の文字列を均一にフォーマットし、自然にソートする方法を紹介します。
1 ??データアレイを準備<BR> 例として、ファイル名のセットを取得しましょう。
$files = ['Img10.png', 'img2.png', 'IMG1.png', 'img20.png', 'img11.png'];
2 ?? array_map <br>を使用したフォーマット要素 それらをすべて小文字に変換したいとします。
$formattedFiles = array_map('strtolower', $files);
より複雑なもの(deスペースや統一された拡張機能など)に対処したい場合は、匿名関数を書くことができます。
$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);
// ステップ2:自然なソート(症例は無感覚です)
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