加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何在Swift中打乱数组?

发布时间:2020-12-14 06:20:26 所属栏目:百科 来源:网络整理
导读:如何随机化或混洗Swift中的数组中的元素?例如,如果我的数组包括52张扑克牌,我想洗牌,以便洗牌。 这个答案详细说明了如何在Swift的各种版本中添加Fisher-Yates(快速统一)shuffle。 Swift 3版本是最宽松的,但是它们至少可以用于数组。每个Swift版本的命名
如何随机化或混洗Swift中的数组中的元素?例如,如果我的数组包括52张扑克牌,我想洗牌,以便洗牌。
这个答案详细说明了如何在Swift的各种版本中添加Fisher-Yates(快速统一)shuffle。 Swift 3版本是最宽松的,但是它们至少可以用于数组。每个Swift版本的命名和行为与该版本的mutating和nonmutating排序方法相匹配。

Swift 3.0

这些扩展添加一个shuffle()方法到任何可变的集合和shuffled()方法到任何序列:

extension MutableCollection where Indices.Iterator.Element == Index {
    /// Shuffles the contents of this collection.
    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }

        for (firstUnshuffled,unshuffledCount) in zip(indices,stride(from: c,to: 1,by: -1)) {
            let d: IndexDistance = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
            guard d != 0 else { continue }
            let i = index(firstUnshuffled,offsetBy: d)
            swap(&self[firstUnshuffled],&self[i])
        }
    }
}

extension Sequence {
    /// Returns an array with the contents of this sequence,shuffled.
    func shuffled() -> [Iterator.Element] {
        var result = Array(self)
        result.shuffle()
        return result
    }
}

let x = [1,2,3].shuffled()
// x == [2,3,1]

let fiveStrings = stride(from: 0,through: 100,by: 5).map(String.init).shuffled()
// fiveStrings == ["20","45","70","30",...]

var numbers = [1,4]
numbers.shuffle()
// numbers == [3,1,4]

Swift 2.0

extension MutableCollectionType where Index == Int {
    /// Shuffle the elements of `self` in-place.
    mutating func shuffleInPlace() {
        // empty and single-element collections don't shuffle
        if count < 2 { return }

        for i in startIndex ..< endIndex - 1 {
            let j = Int(arc4random_uniform(UInt32(count - i))) + i
            guard i != j else { continue }
            swap(&self[i],&self[j])
        }
    }
}

extension CollectionType {
    /// Return a copy of `self` with its elements shuffled.
    func shuffle() -> [Generator.Element] {
        var list = Array(self)
        list.shuffleInPlace()
        return list
    }
}

[1,3].shuffle()
// [2,1]

let fiveStrings = 0.stride(through: 100,by: 5).map(String.init).shuffle()
// ["20",4]
numbers.shuffleInPlace()
// [3,4]

Swift 1.2

shuffle作为函数

这是最简单的版本:在顶层任何地方添加此函数,您可以随机播放数组和切片:

func shuffle<C: MutableCollectionType where C.Index == Int>(var list: C) -> C {
    let c = count(list)
    if c < 2 { return list }
    for i in 0..<(c - 1) {
        let j = Int(arc4random_uniform(UInt32(c - i))) + i
        swap(&list[i],&list[j])
    }
    return list
}
shuffle([1,4,5,6,7,8])        // e.g.,[6,8,5]
shuffle(["hello","goodbye","ciao"])    // e.g.,["ciao","hello"]

shuffle作为突变数组方法

这个扩展将允许你随机播放一个可变的Array实例:

extension Array {
    mutating func shuffle() {
        if count < 2 { return }
        for i in 0..<(count - 1) {
            let j = Int(arc4random_uniform(UInt32(count - i))) + i
            swap(&self[i],&self[j])
        }
    }
}
var numbers = [1,8]
numbers.shuffle()                     // e.g.,numbers == [6,5]

改组为非突变数组方法

此扩展将允许您检索数组实例的随机副本:

extension Array {
    func shuffled() -> [T] {
        if count < 2 { return self }
        var list = self
        for i in 0..<(list.count - 1) {
            let j = Int(arc4random_uniform(UInt32(list.count - i))) + i
            swap(&list[i],&list[j])
        }
        return list
    }
}
let numbers = [1,8]
let mixedup = numbers.shuffled()     // e.g.,mixedup == [6,5]

你可以从this gist得到所有这些更复制粘贴的格式。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读