Rap*_*ael 3 character foundation data-structures swift
对于随机字符串生成器,我认为将其CharacterSet用作要使用的字母表的输入类型会很好,因为诸如此类的预定义集CharacterSet.lowercaseLetters显然很有用(即使它们可能包含比您预期的更多样化的字符集) .
但是,显然您只能查询字符集的成员资格,而不能枚举,更不用说索引它们了。我们得到的只是_.bitmapRepresentation8kb 的数据块,每个 (?) 字符都有一个指示位。但是,即使您按索引剥离单个位i(这不太好,通过面向字节的Data),Character(UnicodeScalar(i))也不会给出正确的字母。这意味着格式有些晦涩——当然,它没有记录在案。
当然,我们可以迭代所有字符(每个平面),但这是一个坏主意,成本方面:20 个字符集可能需要迭代数万个字符。用 CS 术语来说:位向量是稀疏集的(非常)糟糕的实现。为什么他们选择在这里以这种方式进行权衡,我不知道。
我在这里遗漏了什么,或者CharacterSet只是FoundationAPI 中的另一个死胡同?
bitmapRepresentation已被记录。
https://developer.apple.com/documentation/foundation/nscharacterset/1417719-bitmaprepresentation
因此迭代该数据如下:
var offset = 0
for ( var i, w ) in CharacterSet.whitespaces.bitmapRepresentation.enumerated() {
if i % 8193 == 8192 {
offset += 1
continue
}
i -= offset
if w != 0 {
for j in 0 ..< 8 {
if w & ( 1 << j ) != 0 {
print( String( format:"%02X", i * 8 + j ) )
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
09
20
A0
1680
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
200A
200B
202F
205F
3000
Run Code Online (Sandbox Code Playgroud)
根据文档,这是对 Satachito 答案的改进,以支持非连续平面的情况,实际上考虑了平面索引:
extension CharacterSet {
func codePoints() -> [Int] {
var result: [Int] = []
var plane = 0
// following documentation at https://developer.apple.com/documentation/foundation/nscharacterset/1417719-bitmaprepresentation
for (i, w) in bitmapRepresentation.enumerated() {
let k = i % 8193
if k == 8192 {
// plane index byte
plane = Int(w) << 13
continue
}
let base = (plane + k) << 3
for j in 0 ..< 8 where w & 1 << j != 0 {
result.append(base + j)
}
}
return result
}
func printHexValues() {
codePoints().forEach { print(String(format:"%02X", $0)) }
}
}
Run Code Online (Sandbox Code Playgroud)
print("whitespaces:")
CharacterSet.whitespaces.printHexValues()
print()
print("two characters from different planes:")
CharacterSet(charactersIn: "").printHexValues()
Run Code Online (Sandbox Code Playgroud)
whitespaces:
09
20
A0
1680
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
200A
200B
202F
205F
3000
two characters from different planes:
1D6A8
CC791
Run Code Online (Sandbox Code Playgroud)
这实际上比迭代所有字符快 3 到 10 倍:与NSCharacterset中NSArray的先前答案进行比较。
根据你的定义,不,没有“合理”的方式。这就是 NSCharacterSet 存储它的方式。它针对测试成员资格进行了优化,而不是枚举所有成员。
您的循环可以在代码点上增加计数器,或者可以移动位(每个代码点一个),但无论哪种方式,您都必须循环和测试。我的 Mac 上最高的“Ll”字符是 U+1D7CB (#120,779),因此如果您想在运行时计算此字符列表,您的代码将必须至少循环这么多次。有关如何组织位向量的详细信息,请参阅Objective-C 版本的文档。
好消息是速度很快。在我使用了 10 年的 Mac 上使用未优化的代码,只需不到 1/10 秒即可找到所有 1,841 lowercaseLetters。如果这仍然不够快,则可以通过在启动时在后台执行一次来轻松隐藏成本。
| 归档时间: |
|
| 查看次数: |
1005 次 |
| 最近记录: |