Skip to content
This repository has been archived by the owner on Jul 27, 2024. It is now read-only.

Commit

Permalink
fix: sort in intuitive order
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-0acf4 committed Jun 1, 2024
1 parent 8311167 commit a29d917
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 49 deletions.
2 changes: 1 addition & 1 deletion rokahon-server/src/utils/fs_scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class FsScanner {
this.books = [];
for (const dir of this.directories) {
if (!await fs.exists(dir)) {
logger.warn("Cannot resolve root:", dir);
logger.error("Cannot resolve root:", dir);
continue;
}
await this.discoverBooks(dir, dir, this.books);
Expand Down
32 changes: 16 additions & 16 deletions rokahon-server/src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,28 +114,28 @@ function commonPrefix(a: string, b: string) {

/**
* Parse all digits and compare one by one from left to right
* while accounting for entries with similar prefixes.
* * `a_i < b_i`: `-1`
* * `a_i > b_i`: `1`
* * `a == b`: fallback to `a.localeCompare(b)`
*/
export function parseNumThenCompare(a: string, b: string) {
const prefix = commonPrefix(a, b);
const na = a.match(/[0-9]+/g);
const nb = b.match(/[0-9]+/g);

// Check if a and b are of the same 'kind'
if (prefix != "") {
// Note: [0-9]+ will not do since 1.44 should still be lower than 1.5 for example
const na = a.match(/[0-9]/g);
const nb = b.match(/[0-9]/g);
if (na && nb) {
const maxComp = Math.min(na.length, nb.length);
for (let i = 0; i < maxComp; i++) {
const va = parseInt(na[i]);
const vb = parseInt(nb[i]);
if (va > vb) {
return 1;
} else if (va < vb) {
return -1;
}
// Check if a and b are of the same 'kind': ch 1, ch 2, vol 1, vol 2, ..
const sameKind = "" == commonPrefix(a, b);
// Check if 'page-ish': 1.jpg, 2.1.jpg, 2.3.jpg, ..
const startWithNumber = /^[0-9]/.test(a) && /^[0-9]/.test(b);
if (na && nb && (sameKind || startWithNumber)) {
const maxComp = Math.min(na.length, nb.length);
for (let i = 0; i < maxComp; i++) {
const va = parseInt(na[i]);
const vb = parseInt(nb[i]);
if (va > vb) {
return 1;
} else if (va < vb) {
return -1;
}
}
}
Expand Down
90 changes: 58 additions & 32 deletions rokahon-server/tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,64 @@ import { assertSnapshot } from "std/testing/snapshot.ts";
import { parseNumThenCompare } from "../src/utils/utils.ts";
import { assertEquals } from "std/assert/assert_equals.ts";

Deno.test("Sorting entries", () => {
const entries = [
"a",
"chapter 1.1",
"chApter 2",
"chBpter 2",
"chapter 1-2 ... 1",
"vol 6",
"chapter 1.44 - 4",
"chapter 1-2 - 4",
"004 - ch 1.2",
"1- chapter 1-2 - 4",
"vol 4",
"001 - ch 1",
"003 - ch 2",
];
const out = entries.sort(parseNumThenCompare);
assertEquals(out, [
"001 - ch 1",
"003 - ch 2",
"004 - ch 1.2",
"1- chapter 1-2 - 4",
"a",
"chapter 1.1",
"chapter 1-2 ... 1",
"chapter 1-2 - 4",
"chapter 1.44 - 4",
"chApter 2",
"chBpter 2",
"vol 4",
"vol 6",
]);
Deno.test("Sorting entries", async (t) => {
await t.step("Pages", () => {
const entries = [
"2.44.jpg",
"2.4.jpg",
"1.jpg",
"1.png",
"1.jpg",
"2.6.jpg",
];
const out = entries.sort(parseNumThenCompare);
assertEquals(out, [
"1.jpg",
"1.jpg",
"1.png",
"2.4.jpg",
"2.6.jpg",
"2.44.jpg",
]);
});

await t.step("Similar kind", () => {
const entries = [
"a",
"chapter 1.1",
"chApter 2",
"chBpter 2",
"chapter 1-2 ... 1",
"vol 6",
"chapter 1.44 - 4",
"chapter 1-2 - 4",
"004 - ch 1.2",
"1- chapter 1-2 - 4",
"vol 4",
"001 - ch 1",
"003 - ch 2",
"chapter 11",
"chapter 2",
];
const out = entries.sort(parseNumThenCompare);
assertEquals(out, [
"001 - ch 1",
"1- chapter 1-2 - 4",
"a",
"chapter 1-2 - 4",
"chapter 1-2 ... 1",
"chapter 1.1",
"chapter 1.44 - 4",
"chapter 2",
"chApter 2",
"chBpter 2",
"003 - ch 2",
"004 - ch 1.2",
"vol 4",
"vol 6",
"chapter 11",
]);
});
});

Deno.test("Scan directories", async (t) => {
Expand Down

0 comments on commit a29d917

Please sign in to comment.