Swift中的自定义排序顺序

lskq00tm  于 2023-01-29  发布在  Swift
关注(0)|答案(1)|浏览(145)

我有一组字符串需要按非拉丁字母顺序排序。具体来说,我有一个字符串“AiyawbpfmnrhHxXzsSqkgtTdD”,它指定了排序顺序,即“y”在“a”之前,但在“A”之后。如果你感兴趣,这是Manuel de Codage中指定的古埃及象形文字的排序顺序。
在Swift中,是否有一种方便的方法可以为这种类型的排序规则指定 predicate 或其他方法?

xzlaal3s

xzlaal3s1#

首先,将字母表转换为Dictionary,将每个CharacterMap到它在字母表中的整数位置:

import Foundation

let hieroglyphAlphabet = "AiyawbpfmnrhHxXzsSqkgtTdD"

let hieroglyphCodes = Dictionary(
    uniqueKeysWithValues: hieroglyphAlphabet
        .enumerated()
        .map { (key: $0.element, value: $0.offset) }
)

接下来,用一个属性扩展StringProtocol,该属性返回这样的字母位置数组:

extension StringProtocol {
    var hieroglyphEncoding: [Int] { map { hieroglyphCodes[$0] ?? -1 } }
}

我将非字母字符转换为-1,这样它们将被视为小于字母字符。您可以将它们转换为.max以将它们视为大于字符,或者如果需要更特殊的处理,使用比Int更复杂的类型。
现在,您可以使用SequencelexicographicallyPrecedes方法,按hieroglyphEncoding对字符串数组进行排序:

let unsorted = "this is the sort order".components(separatedBy: " ")
let sorted = unsorted.sorted {
    $0.hieroglyphEncoding.lexicographicallyPrecedes($1.hieroglyphEncoding)
}
print(sorted)

输出:

["order", "is", "sort", "the", "this"]

在排序过程中,根据需要重新计算每个字符串的hieroglyphEncoding是没有效率的,因此如果有许多字符串要排序,应该将每个字符串及其编码 Package 到一个 Package 器中进行排序,或者使用Schwartzian transform

相关问题