ge-tool/utils/naturalSort.ts

71 lines
2.0 KiB
TypeScript
Raw Normal View History

2025-12-10 06:41:43 +00:00
/**
* Natural sort utility - Sắp xếp file names theo thứ tự tự nhiên
* dụ: file1, file2, file10 (thay file1, file10, file2)
*/
/**
* Generate natural sort key for a string
*
* @param text - String to generate key for
* @returns Array of mixed strings and numbers for natural sorting
*/
export function naturalSortKey(text: string): (string | number)[] {
return text
.split(/([0-9]+)/)
.filter(Boolean)
.map(part => {
const num = parseInt(part, 10);
return isNaN(num) ? part.toLowerCase() : num;
});
}
/**
* Compare two strings using natural sort order
*
* @param a - First string
* @param b - Second string
* @returns Negative if a < b, 0 if equal, positive if a > b
*/
export function naturalSortCompare(a: string, b: string): number {
const keyA = naturalSortKey(a);
const keyB = naturalSortKey(b);
const minLength = Math.min(keyA.length, keyB.length);
for (let i = 0; i < minLength; i++) {
const partA = keyA[i];
const partB = keyB[i];
if (partA !== partB) {
// Both numbers
if (typeof partA === 'number' && typeof partB === 'number') {
return partA - partB;
}
// Both strings
if (typeof partA === 'string' && typeof partB === 'string') {
return partA.localeCompare(partB);
}
// Number vs string - numbers come first
return typeof partA === 'number' ? -1 : 1;
}
}
// All parts equal, shorter string comes first
return keyA.length - keyB.length;
}
/**
* Sort array of objects by a property using natural sort
*
* @param array - Array to sort
* @param keyFn - Function to extract sort key from object
* @returns Sorted array (new array, not mutated)
*/
export function naturalSort<T>(array: T[], keyFn: (item: T) => string): T[] {
return [...array].sort((a, b) => {
const keyA = keyFn(a);
const keyB = keyFn(b);
return naturalSortCompare(keyA, keyB);
});
}