natsort.js 自然順アルゴリズムソート

JavaScript

とあるプロジェクトで、フォルダを特定の箇所にドラッグ&ドロップすると、フォルダ内の画像を登録できるという機能を実装したのですが、ドロップされたフォルダ内の画像を展開すると、画像の順序がバラバラ...。
複数画像をドロップしたら、順序はドロップした時と同様なのに対し、フォルダで受けるとファイルの順序が保証されていないようです。

# Array.prototype.sort()

まずは 普通に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 とかで表示されているファイル名順とは違うことが分かります。

# natsort

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があるのになぁ。

Last Updated: 2021-9-2 12:36:29