如何在 Swift 中从字符集中获取随机元素

Kev*_*inF 2 random set swift

我有用户已经输入的字符数组。我想从所有字母数字字符、标点字符和符号的组合列表中获取用户尚未输入的随机字符。我已经浏览了文档,但找不到从字符集中获取随机元素的方法,这看起来很奇怪......我觉得我错过了一些明显的东西。

func newRandomCharacter() -> Character {

    let validCharacters: CharacterSet = .alphanumerics.union(.punctuationCharacters).union(.symbols)

    var setOfUsedCharacters = CharacterSet()
    // usedCharacters: [Character]
    usedCharacters.forEach { setOfUsedCharacters.insert(charactersIn: String($0)) }

    let setOfUnusedCharacters = validCharacters.subtracting(setOfUsedCharacters)

    return setOfUnusedCharacters.randomElement() <- ???
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*ier 5

字符集不是集合。它是一个集合代数。

\n

尽管它的名字是“a of”,但它并不是“a Setof Characters”。它是数学意义上的 UnicodeScalar(而非字符)的“集合”:定义是否包含给定 UnicodeScalar 的规则列表。没有直接的方法来枚举这些值。由于 UnicodeScalar 超出了有限范围,因此生成完整列表的方法效率较低,但它非常庞大。

\n

不过我很好奇你会如何使用它。这可能包括许多您不期望的字符,例如 UNDERTIE (\xe2\x80\xbf)、SAMARITAN PUNCTUATION BAU (\xe0\xa0\xb3) 和 THAI CHARACTER FONGMAN (\xe0\xb9\x8f)。您真的想从所有 Unicode 字母数字和标点符号中选择一个随机值吗?(例如,有超过 800 个标点符号,据我粗略统计,可能有 25k 个字母数字。我还没有计算符号,但符号有很多。您在美式键盘上得到一个字符的机会是非常接近于零。)

\n

我希望这是您真正寻找的代码:

\n
let asciiRange = 33...126\nlet randomCharacter = asciiRange.randomElement()\n    .flatMap(UnicodeScalar.init)\n    .flatMap(Character.init)!\n
Run Code Online (Sandbox Code Playgroud)\n

这将返回一个随机的、可打印的 ASCII 字符。

\n

鉴于您的集合在 Unicode 空间中所占比例如此之大,以下是您如何快速获得真正随机的集合:

\n
func randomCharacter() -> Character {\n    // Drops the control characters and SPACE, the private use areas, tags, and the variation selectors.\n    // The full range is 0x00...0x10FFFD\n    let unicodeRange = 0x21...0x2FA1D\n    let validCharacters: CharacterSet = .alphanumerics.union(.punctuationCharacters).union(.symbols)\n\n    repeat {\n        if let c = unicodeRange.randomElement().flatMap(UnicodeScalar.init),\n           validCharacters.contains(c) {\n            return Character(c)\n        }\n    } while true\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我只是不断猜测,直到找到为止。只要您从中选择的集合与整个集合的大小相似,这就会趋于收敛。这可能比Set<Character>通过在类似的空间中行走来生成大量数据更有效。

\n