gpt4 book ai didi

arrays - 如何在 Swift 中打乱数组?

转载 作者:行者123 更新时间:2023-11-30 13:14:15 26 4
gpt4 key购买 nike

.shuffle() 和 .shuffled() 是 Swift 的一部分

<小时/>

原始历史问题:

如何在 Swift 中随机化或打乱数组中的元素?例如,如果我的数组由 52 张扑克牌组成,我想洗牌该数组以便洗牌。

最佳答案

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

swift 4.2+

shuffleshuffled从 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 示例中的用法相同。

<小时/>

swift 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 示例中的用法相同。

<小时/>

swift 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]
<小时/>

swift 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]

关于arrays - 如何在 Swift 中打乱数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38417585/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com