如何在Swift中对数组进行混洗?

如何在Swift中对数组进行混洗?,第1张

如何在Swift中对数组进行混洗?

该答案详细说明了如何在Swift 4.2+中使用快速统一的算法(Fisher-
Yates)进行改组,以及如何在各个早期版本的Swift中添加相同功能。每个Swift版本的命名和行为都与该版本的变异和非变异排序方法匹配。

迅捷4.2+

shuffle
并且
shuffled
是从Swift
4.2开始原生的 用法示例:

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, 2, 3, 4]numbers.shuffle()// numbers == [3, 2, 1, 4]
Swift 4.0和4.1

这些扩展将

shuffle()
方法添加到任何可变集合(数组和不安全的可变缓冲区),并
shuffled()
在任何序列上添加方法:

extension MutableCollection {    /// 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)) { // Change `Int` in the next line to `IndexDistance` in < Swift 4.1 let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount))) let i = index(firstUnshuffled, offsetBy: d) swapAt(firstUnshuffled, i)        }    }}extension Sequence {    /// Returns an array with the contents of this sequence, shuffled.    func shuffled() -> [Element] {        var result = Array(self)        result.shuffle()        return result    }}

与上述Swift 4.2示例中的用法相同。


迅捷3

这些扩展将

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)) { // Change `Int` in the next line to `IndexDistance` in < Swift 3.2 let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount))) guard d != 0 else { continue } let i = index(firstUnshuffled, offsetBy: d) self.swapAt(firstUnshuffled, 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    }}

与上述Swift 4.2示例中的用法相同。


迅捷2

(过时的语言:自2018年7月起,您将无法使用Swift 2.x在iTunes Connect上发布)

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, 2, 3].shuffle()// [2, 3, 1]let fiveStrings = 0.stride(through: 100, by: 5).map(String.init).shuffle()// ["20", "45", "70", "30", ...]var numbers = [1, 2, 3, 4]numbers.shuffleInPlace()// [3, 2, 1, 4]

斯威夫特1.2

(过时的语言:自2018年7月起,您将无法使用Swift 1.x在iTunes Connect上发布)

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, 2, 3, 4, 5, 6, 7, 8]numbers.shuffle()          // e.g., numbers == [6, 1, 8, 3, 2, 4, 7, 5]
shuffled
作为非变异数组方法

通过此扩展,您可以检索

Array
实例的随机组合副本:

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, 2, 3, 4, 5, 6, 7, 8]let mixedup = numbers.shuffled()     // e.g., mixedup == [6, 1, 8, 3, 2, 4, 7, 5]


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5642162.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存