【Swift4】 Array를 Shuffle한다
"아베", "이토", "사토", "스즈키", "타나카", "나카무라", "후지이", "마츠이", "무라타", "요시다"
와 오십음순으로 늘어선 사람명의 배열(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)
}
의 과정을 다음과 같이 두 번 반복하는 것만으로도 편향이 없어집니다.
for _ in 0 ... 1{
for i in 0 ..< anArray.count{
let r = Int(arc4random_uniform(UInt32(anArray.count)))
anArray.swapAt(i, r)
}
}
Reference
이 문제에 관하여(【Swift4】 Array를 Shuffle한다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/BMJr/items/c066b4b55bbd01f74495텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)