You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在fp-ts中如何组合2个及以上Ord实例实现多优先级排序

解决方案

你可以直接用 fp-ts/Ord 内置的组合函数 Ord.combine 拼接多个排序规则,优先级高的规则放在前面,只有当前序规则判断两个元素相等时,才会触发后续规则的判断,全程只需要做一次排序:

import { pipe } from 'fp-ts/function'
import * as S from 'fp-ts/string'
import * as N from 'fp-ts/number'
import * as Ord from 'fp-ts/Ord'
import * as A from 'fp-ts/Array'

const ordStringLength = pipe(N.Ord, Ord.contramap((s: string) => s.length))
const ordString = S.Ord

// 组合规则:优先按长度排序,长度相同按字母序排序
const combinedOrd = pipe(
  ordStringLength,
  Ord.combine(ordString)
)

// 单次调用完成排序
const sorted = pipe(listOfStrings, A.sort(combinedOrd))

你之前连续两次调用A.sort的写法不仅有额外的O(n log n)性能开销,依赖排序稳定性的实现也可能在部分场景下得到不符合预期的结果,用组合Ord的方式可以完全规避这两个问题。

多规则扩展

如果你需要组合更多排序规则,只需要按优先级顺序往后拼接 Ord.combine 即可,比如要实现「先按长度升序、长度相同按首字母降序、首字母相同按全量字符串升序」的逻辑,只需要把对应规则按优先级顺序组合:

// 示例:额外定义按首字母降序的规则
const ordByFirstCharDesc = pipe(
  S.Ord,
  Ord.contramap((s: string) => s[0] ?? ''),
  Ord.reverse
)

const combinedOrd = pipe(
  ordStringLength, // 第一优先级
  Ord.combine(ordByFirstCharDesc), // 第二优先级
  Ord.combine(ordString) // 第三优先级
)

补充说明

Ord.combine 的底层逻辑就是合并两个比较规则,没有额外的性能开销,时间复杂度和单次排序完全一致。如果你需要调整某条规则的排序方向,用 Ord.reverse(对应Ord实例) 包裹即可。


内容的提问来源于stack exchange,提问作者harryg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:36:06