【Swift4】 Array를 Shuffle한다

8172 단어 Swiftarrayshuffle
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)
        }

의 과정을 다음과 같이 두 번 반복하는 것만으로도 편향이 없어집니다.
for _ in 0 ... 1{
        for i in 0 ..< anArray.count{
            let r = Int(arc4random_uniform(UInt32(anArray.count)))
            anArray.swapAt(i, r)
        }
}

좋은 웹페이지 즐겨찾기