打字稿中的字母数字排序
Alphanumeric sorting in typescript
我们如何在打字稿中进行字母数字排序以获得以下系列?
['1_11', '1_10', '1_9'...'1_1','1_0']
是不是应该分开排序?
这将对数组进行排序:
this.array = this.array.sort((a, b) => {
return +a.replace('_', '') > +b.replace('_', '') ? -1 : a === b ? 0 : 1
})
如果您想完全控制分隔值的排序顺序,您将无法避免首先拆分值。下面的解决方案使用 compare2By()
高阶函数让您选择排序键顺序和每个键的 ascending/descending 排序。
(已更新以支持关键的特定排序顺序)
type Comparator<T> = (a: T, b: T) => number;
function compareAsc<T>(a: T, b: T) {
return a < b ? -1 : a > b ? 1 : 0;
}
function compareDesc<T>(a: T, b: T) {
return a < b ? 1 : a > b ? -1 : 0;
}
function compare2By<T extends any[]>(
x = 0,
y = 1,
cmpX: Comparator<T[0]> = compareAsc,
cmpY: Comparator<T[1]> = compareAsc
) {
return (a: T, b: T) =>
cmpX(a[x], b[x]) || cmpY(a[y], b[y]);
}
function sortDelimited(src: string[], sortFn: Comparator<number[]>, del = "_") {
return src
.map((x) => x.split(del))
// optional int coercion, not sure if needed for OP
.map((x) => x.map((y) => parseInt(y)))
.sort(sortFn)
.map((x) => x.join(del));
}
console.log(
JSON.stringify(sortDelimited(
['1_11', '1_10', '1_9', '1_1', '1_0'],
// UPDATED: use total descending order
// for both first and second sort key
compare2By(0, 1, compareDesc, compareDesc)
))
)
// ["1_11","1_10","1_9","1_1","1_0"]
我们如何在打字稿中进行字母数字排序以获得以下系列? ['1_11', '1_10', '1_9'...'1_1','1_0']
是不是应该分开排序?
这将对数组进行排序:
this.array = this.array.sort((a, b) => {
return +a.replace('_', '') > +b.replace('_', '') ? -1 : a === b ? 0 : 1
})
如果您想完全控制分隔值的排序顺序,您将无法避免首先拆分值。下面的解决方案使用 compare2By()
高阶函数让您选择排序键顺序和每个键的 ascending/descending 排序。
(已更新以支持关键的特定排序顺序)
type Comparator<T> = (a: T, b: T) => number;
function compareAsc<T>(a: T, b: T) {
return a < b ? -1 : a > b ? 1 : 0;
}
function compareDesc<T>(a: T, b: T) {
return a < b ? 1 : a > b ? -1 : 0;
}
function compare2By<T extends any[]>(
x = 0,
y = 1,
cmpX: Comparator<T[0]> = compareAsc,
cmpY: Comparator<T[1]> = compareAsc
) {
return (a: T, b: T) =>
cmpX(a[x], b[x]) || cmpY(a[y], b[y]);
}
function sortDelimited(src: string[], sortFn: Comparator<number[]>, del = "_") {
return src
.map((x) => x.split(del))
// optional int coercion, not sure if needed for OP
.map((x) => x.map((y) => parseInt(y)))
.sort(sortFn)
.map((x) => x.join(del));
}
console.log(
JSON.stringify(sortDelimited(
['1_11', '1_10', '1_9', '1_1', '1_0'],
// UPDATED: use total descending order
// for both first and second sort key
compare2By(0, 1, compareDesc, compareDesc)
))
)
// ["1_11","1_10","1_9","1_1","1_0"]