我有一组字符串需要按非拉丁字母顺序排序。具体来说,我有一个字符串“AiyawbpfmnrhHxXzsSqkgtTdD”,它指定了排序顺序,即“y”在“a”之前,但在“A”之后。如果你感兴趣,这是Manuel de Codage中指定的古埃及象形文字的排序顺序。在Swift中,是否有一种方便的方法可以为这种类型的排序规则指定 predicate 或其他方法?
xzlaal3s1#
首先,将字母表转换为Dictionary,将每个CharacterMap到它在字母表中的整数位置:
Dictionary
Character
import Foundation let hieroglyphAlphabet = "AiyawbpfmnrhHxXzsSqkgtTdD" let hieroglyphCodes = Dictionary( uniqueKeysWithValues: hieroglyphAlphabet .enumerated() .map { (key: $0.element, value: $0.offset) } )
接下来,用一个属性扩展StringProtocol,该属性返回这样的字母位置数组:
StringProtocol
extension StringProtocol { var hieroglyphEncoding: [Int] { map { hieroglyphCodes[$0] ?? -1 } } }
我将非字母字符转换为-1,这样它们将被视为小于字母字符。您可以将它们转换为.max以将它们视为大于字符,或者如果需要更特殊的处理,使用比Int更复杂的类型。现在,您可以使用Sequence的lexicographicallyPrecedes方法,按hieroglyphEncoding对字符串数组进行排序:
.max
Int
Sequence
lexicographicallyPrecedes
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。
1条答案
按热度按时间xzlaal3s1#
首先,将字母表转换为
Dictionary
,将每个Character
Map到它在字母表中的整数位置:接下来,用一个属性扩展
StringProtocol
,该属性返回这样的字母位置数组:我将非字母字符转换为-1,这样它们将被视为小于字母字符。您可以将它们转换为
.max
以将它们视为大于字符,或者如果需要更特殊的处理,使用比Int
更复杂的类型。现在,您可以使用
Sequence
的lexicographicallyPrecedes
方法,按hieroglyphEncoding
对字符串数组进行排序:输出:
在排序过程中,根据需要重新计算每个字符串的
hieroglyphEncoding
是没有效率的,因此如果有许多字符串要排序,应该将每个字符串及其编码 Package 到一个 Package 器中进行排序,或者使用Schwartzian transform。