如何将排序方向参数传递给数组sort方法使用的自定义对比函数
解决方案
你现在的问题核心是 Array.prototype.sort 接收的比较函数只支持a、b两个入参,你定义的compareString需要第三个排序方向参数,没法直接传入,通过闭包绑定参数就可以解决,常用两种实现方式:
方式1:直接包装比较函数(改法最小,推荐)
在给sortFn赋值时用匿名函数包装一层,把当前作用域的sortByAsc作为参数传入compareString即可,同时建议你先拷贝原数组再排序,避免原地排序修改原引用数据带来的副作用:
this.userActionsRights$ = combineLatest([this.sortBy$, this.userActionsRights$]).pipe( map(([sortBy, userRights]) => { const { active, direction } = sortBy; const sortByAsc = direction === 'asc'; let sortFn; if (active === 'name') { // 固定第三个参数为当前排序方向 sortFn = (a, b) => compareString(a.name, b.name, sortByAsc) } if (active === 'id') { // compareNumber如果也需要排序方向,用同样方式包装即可 sortFn = (a, b) => compareNumber(a.id, b.id, sortByAsc) } // 先浅拷贝数组再排序,避免修改原userRights数组 return [...userRights].sort(sortFn); }), );
方式2:改造compareString为高阶函数(复用性更高)
如果你的比较函数需要在多处使用,可以直接把compareString改成先接收排序方向、返回符合sort要求的双参数比较函数的形式:
// 修改后的compareString定义 export function compareString(isAsc: boolean) { // 返回sort方法能直接用的双参数比较函数 return (a: string | undefined, b: string | undefined) => { if (a === undefined || a === null) return isAsc ? 1 : -1 if (b === undefined || b === null) return isAsc ? -1 : 1 return isAsc ? b.localeCompare(a) : a.localeCompare(b) } }
调用时只需要提前传入排序方向即可:
if (active === 'name') { const strCompare = compareString(sortByAsc) sortFn = (a, b) => strCompare(a.name, b.name) }
注:你当前
compareString里asc排序时返回b.localeCompare(a)是倒序逻辑,如果和预期排序结果不符,改成a.localeCompare(b)即可。
内容的提问来源于stack exchange,提问作者user14480036
相关产品推荐
相关产品推荐

