Как рандомизировать или перемешать элементы в массиве в Swift? Например, если мой массив состоит из 52 игральных карт, я хочу перетасовать массив, чтобы перетасовать колоду.
Как перетасовать массив в Swift?
Ответ 1
В этом ответе подробно описывается, как перемещаться с быстрым и однородным алгоритмом (Fisher-Yates) в Swift 4. 2+ и как добавить ту же функцию в различные предыдущие версии Swift. Именование и поведение для каждой версии Swift соответствуют методам мутирования и немутации для этой версии.
Swift 4. 2+
  shuffle и  shuffled являются родными, начинающими Swift 4.2. Пример использования:
let x = [1, 2, 3].shuffled()
// x == [2, 3, 1]
let fiveStrings = stride(from: 0, through: 100, by: 5).map(String.init).shuffled()
// fiveStrings == ["20", "45", "70", "30", ...]
var numbers = [1, 2, 3, 4]
numbers.shuffle()
// numbers == [3, 2, 1, 4]
Swift 4.0 и 4.1
 Эти расширения добавляют метод shuffle() к любой изменчивой коллекции (массивы и небезопасные изменяемые буферы) и метод shuffled() для любой последовательности:
extension MutableCollection {
    /// Shuffles the contents of this collection.
    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }
        for (firstUnshuffled, unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
            // Change 'Int' in the next line to 'IndexDistance' in < Swift 4.1
            let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
            let i = index(firstUnshuffled, offsetBy: d)
            swapAt(firstUnshuffled, i)
        }
    }
}
extension Sequence {
    /// Returns an array with the contents of this sequence, shuffled.
    func shuffled() -> [Element] {
        var result = Array(self)
        result.shuffle()
        return result
    }
}
Такое же использование, как в приведенных выше примерах Swift 4.2.
Swift 3
 Эти расширения добавляют метод shuffle() к любой изменчивой коллекции и метод shuffled() для любой последовательности:
extension MutableCollection where Indices.Iterator.Element == Index {
    /// Shuffles the contents of this collection.
    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }
        for (firstUnshuffled , unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
            // Change 'Int' in the next line to 'IndexDistance' in < Swift 3.2
            let d: Int = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
            guard d != 0 else { continue }
            let i = index(firstUnshuffled, offsetBy: d)
            self.swapAt(firstUnshuffled, i)
        }
    }
}
extension Sequence {
    /// Returns an array with the contents of this sequence, shuffled.
    func shuffled() -> [Iterator.Element] {
        var result = Array(self)
        result.shuffle()
        return result
    }
}
Такое же использование, как в приведенных выше примерах Swift 4.2.
Swift 2
(устаревший язык: вы не можете использовать Swift 2.x для публикации в iTunes Connect начиная с июля 2018 года)
extension MutableCollectionType where Index == Int {
    /// Shuffle the elements of 'self' in-place.
    mutating func shuffleInPlace() {
        // empty and single-element collections don't shuffle
        if count < 2 { return }
        for i in startIndex ..< endIndex - 1 {
            let j = Int(arc4random_uniform(UInt32(count - i))) + i
            guard i != j else { continue }
            swap(&self[i], &self[j])
        }
    }
}
extension CollectionType {
    /// Return a copy of 'self' with its elements shuffled.
    func shuffle() -> [Generator.Element] {
        var list = Array(self)
        list.shuffleInPlace()
        return list
    }
}
Применение:
[1, 2, 3].shuffle()
// [2, 3, 1]
let fiveStrings = 0.stride(through: 100, by: 5).map(String.init).shuffle()
// ["20", "45", "70", "30", ...]
var numbers = [1, 2, 3, 4]
numbers.shuffleInPlace()
// [3, 2, 1, 4]
Swift 1.2
(устаревший язык: вы не можете использовать Swift 1.x для публикации в iTunes Connect начиная с июля 2018 года)
 shuffle как метод мутирующих массивов
  Это расширение позволит вам перетасовать изменяемый экземпляр Array на месте:
extension Array {
    mutating func shuffle() {
        if count < 2 { return }
        for i in 0..<(count - 1) {
            let j = Int(arc4random_uniform(UInt32(count - i))) + i
            swap(&self[i], &self[j])
        }
    }
}
var numbers = [1, 2, 3, 4, 5, 6, 7, 8]
numbers.shuffle()                     // e.g., numbers == [6, 1, 8, 3, 2, 4, 7, 5]
 shuffled как метод без мутирующих массивов
  Это расширение позволит вам получить перетасованную копию экземпляра Array:
extension Array {
    func shuffled() -> [T] {
        if count < 2 { return self }
        var list = self
        for i in 0..<(list.count - 1) {
            let j = Int(arc4random_uniform(UInt32(list.count - i))) + i
            swap(&list[i], &list[j])
        }
        return list
    }
}
let numbers = [1, 2, 3, 4, 5, 6, 7, 8]
let mixedup = numbers.shuffled()     // e.g., mixedup == [6, 1, 8, 3, 2, 4, 7, 5]
Ответ 2
Изменить: Как отмечено в других ответах, Swift 4.2, наконец, добавляет случайное число в стандартную библиотеку в комплекте с перетасовкой массива.
 Однако GKRandom/GKRandomDistribution в GameplayKit все еще может быть полезен с новым протоколом RandomNumberGenerator - если вы добавите расширения в RandomNumberGenerator GameplayKit, чтобы соответствовать новому стандартному протоколу библиотеки, вы можете легко получить:
- (которые могут воспроизводить "случайную" последовательность, когда это необходимо для тестирования)
- ГСЧ, которые приносят в жертву устойчивость к скорости
- ГСЧ, которые производят неравномерные распределения
... и по-прежнему используют хорошие новые "родные" случайные API в Swift.
Остальная часть этого ответа касается таких RNG и/или их использования в старых компиляторах Swift.
Здесь есть несколько хороших ответов, а также некоторые хорошие иллюстрации того, почему создание собственного тасования может быть подвержено ошибкам, если вы не будете осторожны.
В iOS 9, macOS 10.11 и tvOS 9 (или позже) вам не нужно писать свои собственные. Там эффективная, правильная реализация Fisher-Yates в GameplayKit (которая, несмотря на название, не только для игр).
Если вы просто хотите уникальную перетасовку:
let shuffled = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: array)
Если вы хотите, чтобы у вас была возможность повторить тасовку или череду перетасовки, выберите и запустите определенный случайный источник; например
let lcg = GKLinearCongruentialRandomSource(seed: mySeedValue)
let shuffled = lcg.arrayByShufflingObjects(in: array)
 В iOS 10/macOS 10.12/tvOS 10 также есть удобный синтаксис для перетасовки через расширение на NSArray. Конечно, это немного громоздко, когда вы используете Swift Array (и он теряет свой тип элемента при возврате в Swift):
let shuffled1 = (array as NSArray).shuffled(using: random) // -> [Any]
let shuffled2 = (array as NSArray).shuffled() // use default random source
Но довольно легко сделать для него поддерживающую тип Swift-оболочку:
extension Array {
    func shuffled(using source: GKRandomSource) -> [Element] {
        return (self as NSArray).shuffled(using: source) as! [Element]
    }
    func shuffled() -> [Element] {
        return (self as NSArray).shuffled() as! [Element]
    }
}
let shuffled3 = array.shuffled(using: random)
let shuffled4 = array.shuffled()
Ответ 3
В Swift 2.0 GameplayKit может прийти на помощь! (поддерживается iOS9 или позже)
import GameplayKit
func shuffle() {
    array = GKRandomSource.sharedRandom().arrayByShufflingObjectsInArray(array)
}
Ответ 4
Здесь что-то возможно немного короче:
sorted(a) {_, _ in arc4random() % 2 == 0}
Ответ 5
Взяв алгоритм Nate, я хотел посмотреть, как это будет выглядеть с помощью Swift 2 и расширений протокола.
Вот что я придумал.
extension MutableCollectionType where Self.Index == Int {
    mutating func shuffleInPlace() {
        let c = self.count
        for i in 0..<(c - 1) {
            let j = Int(arc4random_uniform(UInt32(c - i))) + i
            swap(&self[i], &self[j])
        }
    }
}
extension MutableCollectionType where Self.Index == Int {
    func shuffle() -> Self {
        var r = self
        let c = self.count
        for i in 0..<(c - 1) {
            let j = Int(arc4random_uniform(UInt32(c - i))) + i
            swap(&r[i], &r[j])
        }
        return r
    }
}
Теперь любой MutableCollectionType может использовать эти методы, учитывая, что он использует Int как Index
Ответ 6
В моем случае у меня возникли проблемы с обменом объектами в массиве. Затем я поцарапал себе голову и начал изобретать колесо.
// swift 3.0 ready
extension Array {
    func shuffled() -> [Element] {
        var results = [Element]()
        var indexes = (0 ..< count).map { $0 }
        while indexes.count > 0 {
            let indexOfIndexes = Int(arc4random_uniform(UInt32(indexes.count)))
            let index = indexes[indexOfIndexes]
            results.append(self[index])
            indexes.remove(at: indexOfIndexes)
        }
        return results
    }
}
Ответ 7
Это версия реализации Nate Shisher для Fisher-Yates для Swift 4 (Xcode 9).
extension MutableCollection {
    /// Shuffle the elements of 'self' in-place.
    mutating func shuffle() {
        for i in indices.dropLast() {
            let diff = distance(from: i, to: endIndex)
            let j = index(i, offsetBy: numericCast(arc4random_uniform(numericCast(diff))))
            swapAt(i, j)
        }
    }
}
extension Collection {
    /// Return a copy of 'self' with its elements shuffled
    func shuffled() -> [Element] {
        var list = Array(self)
        list.shuffle()
        return list
    }
}
Изменения следующие:
-  Индекс ограничений Indices.Iterator.Element == Indexтеперь является частью протоколаCollection, и его больше не нужно накладывать на расширение.
-  Обмен элементами должен выполняться путем вызова swapAt()в коллекции, сравните SE-0173 AddMutableCollection.swapAt(_:_:).
-  Elementявляется псевдонимом дляIterator.Element.
Ответ 8
Это то, что я использую:
func newShuffledArray(array:NSArray) -> NSArray {
    var mutableArray = array.mutableCopy() as! NSMutableArray
    var count = mutableArray.count
    if count>1 {
        for var i=count-1;i>0;--i{
            mutableArray.exchangeObjectAtIndex(i, withObjectAtIndex: Int(arc4random_uniform(UInt32(i+1))))
        }
    }
    return mutableArray as NSArray
}
Ответ 9
Swift 4 Перемешать элементы массива в цикле for, где я - коэффициент смешивания
var cards = [Int]() //Some Array
let i = 4 // is the mixing ratio
func shuffleCards() {
    for _ in 0 ..< cards.count * i {
        let card = cards.remove(at: Int(arc4random_uniform(UInt32(cards.count))))
        cards.insert(card, at: Int(arc4random_uniform(UInt32(cards.count))))
    }
}
Или с расширением Int
func shuffleCards() {
    for _ in 0 ..< cards.count * i {
        let card = cards.remove(at: cards.count.arc4random)
        cards.insert(card, at: cards.count.arc4random)
    }
}
extension Int {
    var arc4random: Int {
        if self > 0 {
            print("Arc for random positiv self \(Int(arc4random_uniform(UInt32(self))))")
        return Int(arc4random_uniform(UInt32(self)))
        } else if self < 0 {
            print("Arc for random negotiv self \(-Int(arc4random_uniform(UInt32(abs(self)))))")
            return -Int(arc4random_uniform(UInt32(abs(self))))
        } else {
            print("Arc for random equal 0")
            return 0
        }
    }
}
Ответ 10
С Swift 3, если вы хотите перетасовать массив на месте или получить новый перетасованный массив из массива, AnyIterator может помочь тебе. Идея состоит в том, чтобы создать массив индексов из вашего массива, чтобы перетасовать эти индексы с помощью экземпляра AnyIterator и swap(_:_:) и сопоставьте каждый элемент этого экземпляра AnyIterator с соответствующим элементом массива.
Следующий код игровой площадки показывает, как он работает:
import Darwin // required for arc4random_uniform
let array = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
var indexArray = Array(array.indices)
var index = indexArray.endIndex
let indexIterator: AnyIterator<Int> = AnyIterator {
    guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
        else { return nil }
    index = nextIndex
    let randomIndex = Int(arc4random_uniform(UInt32(index)))
    if randomIndex != index {
        swap(&indexArray[randomIndex], &indexArray[index])
    }
    return indexArray[index]
}
let newArray = indexIterator.map { array[$0] }
print(newArray) // may print: ["Jock", "Ellie", "Sue Ellen", "JR", "Pamela", "Bobby"]
Вы можете реорганизовать предыдущий код и создать функцию shuffled() внутри расширения Array, чтобы получить новый перетасованный массив из массива:
import Darwin // required for arc4random_uniform
extension Array {
    func shuffled() -> Array<Element> {
        var indexArray = Array<Int>(indices)        
        var index = indexArray.endIndex
        let indexIterator = AnyIterator<Int> {
            guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
                else { return nil }
            index = nextIndex                
            let randomIndex = Int(arc4random_uniform(UInt32(index)))
            if randomIndex != index {
                swap(&indexArray[randomIndex], &indexArray[index])
            }
            return indexArray[index]
        }
        return indexIterator.map { self[$0] }
    }
}
Использование:
let array = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
let newArray = array.shuffled()
print(newArray) // may print: ["Bobby", "Pamela", "Jock", "Ellie", "JR", "Sue Ellen"]
let emptyArray = [String]()
let newEmptyArray = emptyArray.shuffled()
print(newEmptyArray) // prints: []
В качестве альтернативы предыдущему коду вы можете создать функцию shuffle() внутри расширения Array, чтобы перетасовать массив на месте:
import Darwin // required for arc4random_uniform
extension Array {
    mutating func shuffle() {
        var indexArray = Array<Int>(indices)
        var index = indexArray.endIndex
        let indexIterator = AnyIterator<Int> {
            guard let nextIndex = indexArray.index(index, offsetBy: -1, limitedBy: indexArray.startIndex)
                else { return nil }
            index = nextIndex                
            let randomIndex = Int(arc4random_uniform(UInt32(index)))
            if randomIndex != index {
                swap(&indexArray[randomIndex], &indexArray[index])
            }
            return indexArray[index]
        }
        self = indexIterator.map { self[$0] }
    }
}
Использование:
var mutatingArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
mutatingArray.shuffle()
print(mutatingArray) // may print ["Sue Ellen", "Pamela", "Jock", "Ellie", "Bobby", "JR"]
Ответ 11
Решение Swift 3, после ответа @Nate Cook: (работайте, если индекс начинается с 0, см. комментарии ниже)
extension Collection {
    /// Return a copy of `self` with its elements shuffled
    func shuffle() -> [Generator.Element] {
        var list = Array(self)
        list.shuffleInPlace()
        return list
    } }
extension MutableCollection where Index == Int {
    /// Shuffle the elements of `self` in-place.
    mutating func shuffleInPlace() {
        // empty and single-element collections don't shuffle
        if count < 2 { return }
        let countInt = count as! Int
    for i in 0..<countInt - 1 {
        let j = Int(arc4random_uniform(UInt32(countInt - i))) + i
            guard i != j else { continue }
            swap(&self[i], &self[j])
        }
    }
}
Ответ 12
Вот как это делается простейшим способом. import Gamplaykit для вашего VC и используйте приведенный ниже код. Протестировано в Xcode 8.
 import GameplayKit
 let array: NSArray = ["Jock", "Ellie", "Sue Ellen", "Bobby", "JR", "Pamela"]
 override func viewDidLoad() {
    super.viewDidLoad()
    print(array.shuffled())  
}
Если вы хотите получить перетасованную строку из массива, вы можете использовать код ниже.
func suffleString() {
    let ShuffleArray = array.shuffled()
    suffleString.text = ShuffleArray.first as? String
    print(suffleString.text!)
}
Ответ 13
Составьте статью Fisher-Yates shuffle на Wikipedia
Swift 3.1.4.0
а). Карандашный метод:
func shuffle<T>(_ array:inout [T]){
    var temp = [T]()
    for _  in array{
        /*Generating random number with length*/
        let random = arc4random_uniform(UInt32(array.count))
        /*Take the element from array*/
        let elementTaken = array[Int(random)]
        /*Append it to new tempArray*/
        temp.append(elementTaken)
        /*Remove the element from array*/
        array.remove(at: Int(random))
    }
    /* array = tempArray*/
    array = temp
}
б). Современный метод: (версия Durstenfeld)
func shuffle<T>(_ array:inout [T]){
    var length = array.count
    for _  in array{
        /*Generating random number with length*/
        let random = arc4random_uniform(UInt32(length))
        /*Check before index of two elements not same*/
        if length-1 != Int(random){
            swap(&array[length-1], &array[Int(random)])
        }
        length -= 1
    }
}
 Extension:
а). Карандашный метод:
extension Array{
    mutating func shuffled(){
        var temp = [Element]()
        for _  in self{
            /*Generating random number with length*/
            let random = arc4random_uniform(UInt32(self.count))
            /*Take the element from array*/
            let elementTaken = self[Int(random)]
            /*Append it to new tempArray*/
            temp.append(elementTaken)
            /*Remove the element from array*/
            self.remove(at: Int(random))
        }
        /* array = tempArray*/
        self = temp
    }
}
б). Современный метод: (версия Durstenfeld)
extension Array{
    mutating func shuffled(){
        var length = self.count
        for _  in self{
            /*Generating random number with length*/
            let random = arc4random_uniform(UInt32(length))
            /*Check before index of two elements not same*/
            if length-1 != Int(random){
                /*Swaping elements, If same index then there is no swap*/
               // swap(&self[length-1], &self[Int(random)]) -> Swift 3.0
                self.swapAt(length-1, Int(random)) //-> Swift 4.0
            }
            length -= 1
        }
    }
}
Ссылка:
/* By using shuffle functions*/
var a = [1,2,3,4,5,6,7,8,9,10]
for _ in 1...10{
    self.shuffle(&a)
    /*For shuffled extension, a.shuffled()*/
    print(a)
}
Примечание: Вы также можете использовать пустой массив.
Вывод:
[6, 2, 10, 5, 1, 8, 9, 4, 3, 7]
[7, 1, 9, 8, 2, 10, 5, 6, 4, 3]
[8, 9, 6, 10, 5, 2, 7, 4, 3, 1]
[10, 1, 7, 4, 8, 9, 3, 5, 2, 6]
[8, 1, 6, 9, 3, 7, 4, 5, 10, 2]
[4, 3, 7, 9, 1, 5, 8, 6, 10, 2]
[7, 3, 4, 9, 10, 1, 6, 5, 2, 8]
[3, 6, 2, 4, 5, 8, 9, 7, 1, 10]
[5, 1, 2, 10, 6, 9, 7, 3, 8, 4]
[7, 9, 3, 8, 2, 1, 5, 4, 6, 10]
Пожалуйста, дайте мне знать, если какие-либо запросы, другая версия Swift будет проверяться в ближайшее время.
Ответ 14
Вы также можете использовать универсальную функцию swap и реализовать упомянутые 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)))])
}
Ответ 15
работает!!. организмы - это массив для перетасовки.
extension Array
{
    /** Randomizes the order of an array 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)")
Ответ 16
 В Swift 4.2 теперь есть метод как изменчивого shuffle и неизменяемого shuffled. Вы можете прочитать больше о генерации случайных чисел и прочее массив здесь.
Ответ 17
Вот как перетасовать один массив с семенем в Swift 3.0.
extension MutableCollection where Indices.Iterator.Element == Index {
    mutating func shuffle() {
        let c = count
        guard c > 1 else { return }
        for (firstUnshuffled , unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
            srand48(seedNumber)
            let number:Int = numericCast(unshuffledCount)
            let r = floor(drand48() * Double(number))
            let d: IndexDistance = numericCast(Int(r))
            guard d != 0 else { continue }
            let i = index(firstUnshuffled, offsetBy: d)
            swap(&self[firstUnshuffled], &self[i])
        }
    }
}
Ответ 18
let shuffl = GKRandomSource.sharedRandom().arrayByShufflingObjects(in: arrayObject)
Ответ 19
Это то, что я использую:
import GameplayKit
extension Collection {
    func shuffled() -> [Iterator.Element] {
        let shuffledArray = (self as? NSArray)?.shuffled()
        let outputArray = shuffledArray as? [Iterator.Element]
        return outputArray ?? []
    }
    mutating func shuffle() {
        if let selfShuffled = self.shuffled() as? Self {
            self = selfShuffled
        }
    }
}
// Usage example:
var numbers = [1,2,3,4,5]
numbers.shuffle()
print(numbers) // output example: [2, 3, 5, 4, 1]
print([10, "hi", 9.0].shuffled()) // output example: [hi, 10, 9]
Ответ 20
Простой пример:
extension Array {
    mutating func shuffled() {
        for _ in self {
            // generate random indexes that will be swapped
            var (a, b) = (Int(arc4random_uniform(UInt32(self.count - 1))), Int(arc4random_uniform(UInt32(self.count - 1))))
            if a == b { // if the same indexes are generated swap the first and last
                a = 0
                b = self.count - 1
            }
            swap(&self[a], &self[b])
        }
    }
}
var array = [1,2,3,4,5,6,7,8,9,10]
array.shuffled()
print(array) // [9, 8, 3, 5, 7, 6, 4, 2, 1, 10]
Ответ 21
Расширение рабочей матрицы (мутирующий и не мутирующий)
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
    }
}
 Call Non-Mutating 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)
 Этот array печатает в произвольном порядке.
 Call Mutating 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) 
 Этот array печатает в своем текущем порядке, который уже был случайным образом перетасован.
Надеется, что это работает для всех, если у вас есть какие-либо вопросы, предложения или комментарии, не стесняйтесь спрашивать!
Ответ 22
В SWIFT 4
func createShuffledSequenceOfNumbers(max:UInt)->[UInt] {
    var array:[UInt]! = []
    var myArray:[UInt]! = []
    for i in 1...max {
        myArray.append(i)
    }
    for i in 1...max {
        array.append(i)
    }
    var tempArray:[Int]! = []
    for index in 0...(myArray.count - 1) {
        var isNotFinded:Bool = true
        while(isNotFinded){
            let randomNumber = arc4random_uniform(UInt32(myArray.count))
            let randomIndex = Int(randomNumber)
            if(!tempArray.contains(randomIndex)){
                tempArray.append(randomIndex)
                array[randomIndex] = myArray[index]
                isNotFinded = false
            }
        }
    }
    return array
}
Ответ 23
Если вы хотите использовать простую функцию цикла Swift For, используйте это ->
var arrayItems = ["A1", "B2", "C3", "D4", "E5", "F6", "G7", "H8", "X9", "Y10", "Z11"]
var shuffledArray = [String]()
for i in 0..<arrayItems.count
{
    let randomObject = Int(arc4random_uniform(UInt32(items.count)))
    shuffledArray.append(items[randomObject])
    items.remove(at: randomObject)
}
print(shuffledArray)
Swift Array с использованием расширения ->
extension Array {
    // Order Randomize
    mutating func shuffle() {
        for _ in 0..<count {
            sort { (_,_) in arc4random() < arc4random() }
        }
    }
}
Ответ 24
Начиная с Swift 4.2 есть две удобные функции:
// shuffles the array in place
myArray.shuffle()
а также
// generates a new array with shuffled elements of the old array
let newArray = myArray.shuffled()
Ответ 25
Вот какой код работает на детской площадке. Вам не нужно будет импортировать Darwin в настоящий проект Xcode.
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)
Ответ 26
Он останавливается на "swap (& self [i], & self [j])", когда я обновляю версию xCode до 7.4 beta. 
фатальная ошибка: замена места с самим собой не поддерживается 
Я нашел причину, по которой я = j (функция swap будет взорваться)
Итак, я добавляю условие ниже
if (i != j){
    swap(&list[i], &list[j])
}
YA! Это нормально для меня.
