とあるプロジェクトで、フォルダを特定の箇所にドラッグ&ドロップすると、フォルダ内の画像を登録できるという機能を実装したのですが、ドロップされたフォルダ内の画像を展開すると、画像の順序がバラバラ...。
複数画像をドロップしたら、順序はドロップした時と同様なのに対し、フォルダで受けるとファイルの順序が保証されていないようです。
まずは 普通にsort()
を使って、以下のような配列にソートを実行してみます。
const images = [
"image22.jpg",
"image1.jpg",
"image3.jpg",
"image222.jpg",
"image2.jpg",
"image11.jpg"
];
console.log(images.sort());
/*
(6) ["image1.jpg", "image11.jpg", "image2.jpg", "image22.jpg", "image222.jpg", "image3.jpg"]
0: "image1.jpg"
1: "image11.jpg"
2: "image2.jpg"
3: "image22.jpg"
4: "image222.jpg"
5: "image3.jpg"
*/
確かにきちんとソートされてるんですが、windows とかで表示されているファイル名順とは違うことが分かります。
sort()
では意図したソートができないので、自然順アルゴリズムでソートできる natsort というライブラリを使ってソートします。
natsort | npm (opens new window)
$ npm install natsort --save
Vue のコンポーネント内で使う場合、import
を記述。
<script>
import natsort from 'natsort'
export default {}
</script>
使い方は以下のようにシンプルで、先程の配列を natsort を使ってソートしてみます。
console.log(images.sort(natsort()));
/*
(6) ["image1.jpg", "image12.jpg", "image3.jpg", "image11.jpg", "image22.jpg", "image222.jpg"]
0: "image1.jpg"
1: "image2.jpg"
2: "image3.jpg"
3: "image11.jpg"
4: "image22.jpg"
5: "image222.jpg"
*/
配列の要素がobject
の場合は、以下のように実装。
const images = [
{
name: "image22.jpg"
},
{
name: "image1.jpg"
},
{
name: "image3.jpg"
},
{
name: "image222.jpg"
},
{
name: "image2.jpg"
},
{
name: "image11.jpg"
}
];
const sorter = natsort();
images.sort(function(a, b) {
return sorter(a.name, b.name);
});
PHP には標準でnatsort
があるのになぁ。