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


原历史问题:

我如何随机或洗牌在Swift数组中的元素?例如,如果我的数组包含52张扑克牌,我想要洗牌数组以洗牌牌组。


当前回答

工作阵列扩展(突变和非突变)

Swift 4.1 / Xcode 9

上面的答案已弃用,所以我自己创建了自己的扩展,在Swift的最新版本Swift 4.1 (Xcode 9)中洗牌数组:

extension Array {

// Non-mutating shuffle
    var shuffled : Array {
        let totalCount : Int = self.count
        var shuffledArray : Array = []
        var count : Int = totalCount
        var tempArray : Array = self
        for _ in 0..<totalCount {
            let randomIndex : Int = Int(arc4random_uniform(UInt32(count)))
            let randomElement : Element = tempArray.remove(at: randomIndex)
            shuffledArray.append(randomElement)
            count -= 1
        }
        return shuffledArray
    }

// Mutating shuffle
    mutating func shuffle() {
        let totalCount : Int = self.count
        var shuffledArray : Array = []
        var count : Int = totalCount
        var tempArray : Array = self
        for _ in 0..<totalCount {
            let randomIndex : Int = Int(arc4random_uniform(UInt32(count)))
            let randomElement : Element = tempArray.remove(at: randomIndex)
            shuffledArray.append(randomElement)
            count -= 1
        }
        self = shuffledArray
    }
}

调用非突变Shuffle [Array] -> [Array]:

let array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

print(array.shuffled)

这将以随机顺序打印数组。


调用Shuffle [Array] = [Array]:

var array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

array.shuffle() 
// The array has now been mutated and contains all of its initial 
// values, but in a randomized shuffled order

print(array) 

这将打印数组的当前顺序,该顺序已经被随机打乱。


希望这对每个人都有用,如果你有任何问题,建议或评论,请随时提问!

其他回答

当我将xCode版本升级到7.4 beta时,它停止在“swap(&self[i], &self[j])”。 致命错误:不支持与自身交换位置

我找到了I = j的原因(交换函数将爆炸)

所以我添加了一个条件,如下所示

if (i != j){
    swap(&list[i], &list[j])
}

丫!对我来说没问题。

你也可以使用通用交换函数,实现前面提到的Fisher-Yates:

for idx in 0..<arr.count {
  let rnd = Int(arc4random_uniform(UInt32(idx)))
  if rnd != idx {
    swap(&arr[idx], &arr[rnd])
  }
}

或者更简洁:

for idx in 0..<steps.count {
  swap(&steps[idx], &steps[Int(arc4random_uniform(UInt32(idx)))])
}

这是一些在playground上运行的代码。你不需要在实际的Xcode项目中导入Darwin。

import darwin

var a = [1,2,3,4,5,6,7]

func shuffle<ItemType>(item1: ItemType, item2: ItemType) -> Bool {
    return drand48() > 0.5
}

sort(a, shuffle)

println(a)

工作! !生物体是要洗牌的数组。

extension Array
{
    /** Randomizes the order of an array's elements. */
    mutating func shuffle()
    {
        for _ in 0..<10
        {
            sort { (_,_) in arc4random() < arc4random() }
        }
    }
}

var organisms = [
    "ant",  "bacteria", "cougar",
    "dog",  "elephant", "firefly",
    "goat", "hedgehog", "iguana"]

print("Original: \(organisms)")

organisms.shuffle()

print("Shuffled: \(organisms)")

在Swift 2.0中,GameplayKit可能会来拯救你!(iOS9或更高版本支持)

import GameplayKit

func shuffle() {
    array = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(array)
}