【Swift4】 ArrayをShuffleする
Swift4で配列をシャッフルする簡単なサンプルを提示します。
"阿部","伊東","佐藤","鈴木","田中","中村","藤井","松井","村田","吉田"
と五十音順に並んだ人名の配列(anArray)をシャッフルします。
var anArray = ["阿部","伊東","佐藤","鈴木","田中","中村","藤井","松井","村田","吉田"]
//shuffle前print
print("shuffle前")
for i in anArray{
print("\(i)")
}
//shuffleする
for i in 0 ..< anArray.count{
let r = Int(arc4random_uniform(UInt32(anArray.count)))
anArray.swapAt(i, r)
}
//shuffle後print
print("shuffle後")
for i in anArray{
print("\(i)")
}
print結果は以下のようになります。
shuffle前
阿部
伊東
佐藤
鈴木
田中
中村
藤井
松井
村田
吉田
shuffle後
佐藤
村田
田中
阿部
鈴木
藤井
伊東
中村
吉田
松井
※※追記※※
上記のコードでは結果に偏りが生じるという御指摘を、@t-ae 様より頂きました。そこで以下の新スレで検証してみました。
たかがシャッフル、されどシャッフル 〜"permute-with-all" order biasの検証〜
結論をいいますと、上記コードで生じる偏りは「かなり大きい」です。
従いまして、上記コードは使わない方がよいです。
解決策
let r = Int(arc4random_uniform(UInt32(anArray.count)))
を以下のように変更します。
let r = Int(arc4random_uniform(UInt32(anArray.count - i))) + i
これにより、結果の偏りは無くなります。
以下のようにextensionにする方法もあります。
extension Array{
mutating func shuffle(){
let n = self.count
for i in 0 ..< n{
let r = Int(arc4random_uniform(UInt32(n - i))) + i
self.swapAt(i, r)
}
}
}
別解
for i in 0 ..< anArray.count{
let r = Int(arc4random_uniform(UInt32(anArray.count)))
anArray.swapAt(i, r)
}
のプロセスを以下のように2回繰り返すだけでも偏りがなくなります。
for _ in 0 ... 1{
for i in 0 ..< anArray.count{
let r = Int(arc4random_uniform(UInt32(anArray.count)))
anArray.swapAt(i, r)
}
}
Author And Source
この問題について(【Swift4】 ArrayをShuffleする), 我々は、より多くの情報をここで見つけました https://qiita.com/BMJr/items/c066b4b55bbd01f74495著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .