问题描述
从 Swift 1.2 开始,Apple 引入了 Set 集合类型.
As of Swift 1.2, Apple introduces Set collection type.
说,我有一套像:
var set = Set<Int>(arrayLiteral: 1, 2, 3, 4, 5)
现在我想从中得到一个随机元素.问题是如何?Set 不像 Array 那样提供 subscript(Int).相反,它有 subscript(SetIndex<T>).但首先, SetIndex<T> 没有可访问的初始化程序(因此,我不能只创建具有所需偏移量的索引),其次,即使我可以获得第一个元素的索引一个集合 (var startIndex = set.startIndex) 那么我可以得到第 N 个索引的唯一方法是通过连续调用 successor().
Now I want to get a random element out of it. Question is how? Set does not provide subscript(Int) like Array does. Instead it has subscript(SetIndex<T>). But firstly, SetIndex<T> does not have accessible initializers (hence, I can not just create an index with the offset I need), and secondly even if I can get the index for a first element in a set (var startIndex = set.startIndex) then the only way I can get to the N-th index is through consecutive calls to successor().
因此,我目前只能看到 2 个选项,既丑又贵:
Therefore, I can see only 2 options at the moment, both ugly and expensive:
- 将集合转换为数组(
var array = [Int](set))并使用它的下标(完全接受Int);或 - 获取集合中第一个元素的索引,遍历
successor()方法链得到第N个索引,然后通过集合的下标读取对应的元素.
- Convert the set into array (
var array = [Int](set)) and use its subscript (which perfectly acceptsInt); or - Get index of a first element in a set, traverse the chain of
successor()methods to get to the N-th index, and then read corresponding element via set's subscript.
我想念其他方式吗?
推荐答案
可能最好的方法是 advance 为你走 successor:
Probably the best approach is advance which walks successor for you:
func randomElementIndex<T>(s: Set<T>) -> T {
let n = Int(arc4random_uniform(UInt32(s.count)))
let i = advance(s.startIndex, n)
return s[i]
}
(嘿;注意到您实际上已更新问题以包含此答案,然后再将其添加到我的答案中……嗯,这仍然是个好主意,我也学到了一些东西.:D)
( Heh; noticed you actually updated the question to include this answer before I added it to my answer... well, still a good idea and I learned something too. :D)
你也可以遍历集合而不是索引(这是我的第一个想法,但后来我想起了 advance).
You can also walk the set rather than the indices (this was my first thought, but then I remembered advance).
func randomElement<T>(s: Set<T>) -> T {
let n = Int(arc4random_uniform(UInt32(s.count)))
for (i, e) in enumerate(s) {
if i == n { return e }
}
fatalError("The above loop must succeed")
}
这篇关于如何从 Swift 中的集合中获取随机元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!


大气响应式网络建站服务公司织梦模板
高端大气html5设计公司网站源码
织梦dede网页模板下载素材销售下载站平台(带会员中心带筛选)
财税代理公司注册代理记账网站织梦模板(带手机端)
成人高考自考在职研究生教育机构网站源码(带手机端)
高端HTML5响应式企业集团通用类网站织梦模板(自适应手机端)