Kotlin如何按startsWith()对字符串列表排序,让前缀匹配结果置顶
基于startsWith()优先排序字符串列表的高效实现
你现有的实现需要遍历列表两次,分别筛选匹配项和非匹配项,同等数据量下遍历开销是单次遍历的两倍,列表规模越大冗余开销越明显。
方案1:单次遍历分区(性能最优)
直接用Kotlin标准库提供的partition函数,单次遍历即可将列表拆分为「匹配startsWith规则」和「不匹配规则」两个子列表,时间复杂度为O(n),比原有实现降低一倍遍历开销:
val (matched, unmatched) = list.partition { it.startsWith(query, true) } val resultList = matched + unmatched
如果需要对两个分组内部做自然排序,仅需对两个子列表单独排序即可:
val resultList = matched.sorted() + unmatched.sorted()
方案2:权重排序(灵活度更高)
如果需要结合其他排序规则,不想拆分列表再合并,可以给匹配项设置更低的排序权重,直接通过sortedBy实现,时间复杂度为O(n log n):
val resultList = list.sortedBy { if (it.startsWith(query, true)) 0 else 1 }
如果需要同时支持匹配项内部升序、非匹配项内部升序,可以扩展权重逻辑:
val resultList = list.sortedWith(compareBy<String>( { if (it.startsWith(query, true)) 0 else 1 }, { it } ))
适用场景对比
- 列表规模较大(万条以上)且仅需区分匹配/非匹配分组:优先选
partition方案,线性遍历的性能远高于排序方案 - 列表规模较小或需要多维度排序:优先选权重排序方案,代码更简洁易维护
内容的提问来源于stack exchange,提问作者Antonis Radz
相关产品推荐
相关产品推荐

