2015-09-21 19 views
9

mam to rozszerzenie, które stworzą nową tablicę, które mają grupę tablic losowo z danej tablicy:fatal error: zamiana lokalizacji z siebie nie jest obsługiwana Swift 2.0

extension Array { 
    var shuffle:[Element] { 
     var elements = self 
     for index in 0..<elements.count { 
      swap(&elements[index], &elements[ Int(arc4random_uniform(UInt32(elements.count-index)))+index ]) 
     } 
     return elements 
    } 
    func groupOf(n:Int)-> [[Element]] { 
     var result:[[Element]]=[] 
     for i in 0...(count/n)-1 { 
      var tempArray:[Element] = [] 
      for index in 0...n-1 { 
       tempArray.append(self[index+(i*n)]) 
      } 
      result.append(tempArray) 
     } 

     return result 
    } 
} 

i używam go jak to:

let mainArr = Array(1...60) 
let suffeldArr = mainArr.shuffle.groupOf(10) 
print(suffeldArr) 

I będzie drukować jak:

[[10 random element between 1 to 60], [10 random element between 1 to 60], [10 random element between 1 to 60], [10 random element between 1 to 60], [10 random element between 1 to 60], [10 random element between 1 to 60]] 

Ale to daje mi błąd podczas wykonywania tim e na tej linii:

swap(&elements[index], &elements[ Int(arc4random_uniform(UInt32(elements.count-index)))+index ]) 

który mówi:

fatal error: swapping a location with itself is not supported

To działa dobrze w 1.2, ale teraz to nie działa w wersji 2.0.

Nie wiem, jak rozwiązać ten problem.

+0

nocie kod w http://stackoverflow.com/a/24029847/1187415 został zaktualizowany w celu rozwiązania tego problemu: http://stackoverflow.com/questions/24026510/how-do-i-shuffle-an-array-in -swift/24029847 # comment52863556_24029847 –

+0

Dzięki ... @MartinR –

Odpowiedz

11

Próbujesz zamienić element z siebie, trzeba będzie wykonać test, aby sprawdzić, czy nie próbują zamienić element w tym samym miejscu w tablicy, tak jak poniżej:

extension Array { 
    var shuffle:[Element] { 
     var elements = self 
     for index in 0..<elements.count { 
      let newIndex = Int(arc4random_uniform(UInt32(elements.count-index)))+index 
      if index != newIndex { // Check if you are not trying to swap an element with itself 
       swap(&elements[index], &elements[newIndex]) 
      } 
     } 
     return elements 
    } 
    func groupOf(n:Int)-> [[Element]] { 
     var result:[[Element]]=[] 
     for i in 0...(count/n)-1 { 
      var tempArray:[Element] = [] 
      for index in 0...n-1 { 
       tempArray.append(self[index+(i*n)]) 
      } 
      result.append(tempArray) 
     } 

     return result 
    } 
} 
+0

Tak, działa! Dzięki za pomoc .. :) –

+0

@DharmeshKheni również sprawdź tę odpowiedź dla czystego i prostego algorytmu tasowania Fisher-Yates: http://stackoverflow.com/a/24029847/1009013 – vrwim

+0

tak Martin już zasugerował, że .. :) –