如何从 Swift 的集合中获取随机元素? [英] How to get random element from a set in Swift?

查看:48
本文介绍了如何从 Swift 的集合中获取随机元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从 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).但首先,SetIndex 没有可访问的初始值设定项(因此,我不能只用我需要的偏移量创建索引),其次即使我可以获得第一个元素的索引一个集合 (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 accepts Int); 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 的集合中获取随机元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆