2016-11-01 418 views
-1

我需要隨機化一個應用程序的數組我試圖在swift中構建,並測試我創建的函數,並將其放入操作數組中。我意識到這個問題已經在這裏問:How do I shuffle an array in Swift? 但我只是想知道爲什麼這種特定的方式不起作用。這是我的代碼:隨機化一個數組

import UIKit 

var arrayOne : [String] = ["", "", "", "", ""] 

func randomizeArray(array : [String]) -> [String] { 
    var randomizedArray : [String] = [] 
    var copyOfArray : [String] = array 
    repeat { 
     let arrayCount : Int = array.count - 1 
     let randomElement : Int = Int(arc4random_uniform(UInt32(arrayCount))) 
     let arraySlice : String = array[randomElement] 
     randomizedArray.append(arraySlice) 
     copyOfArray.remove(at : randomElement) 
    } while array.count > 0 
    return randomizedArray 
} 

print(randomizeArray(array : arrayOne)) 

當我嘗試使用數組1打印函數時,它說「致命錯誤:索引超出範圍」。任何想法爲什麼發生這種情況

+2

對於包含5個元素的數組,您可以輕鬆調試問題。在Xcode中單步執行代碼,您會很快看到問題出在哪裏。 –

+2

然後擺脫所有不必要的類型註釋... –

回答

0

When I try to print the function using array one, it says "Fatal error: index is out of range." Any ideas why this happened?

我來回答這個問題。

屬性arrayCount(即array.count)在循環內是固定的:在您的示例中,固定爲4。這意味着循環將永不終止(array.count > 0總是true)。此外,由於您將此數字用作隨機數生成的上限,因此您可能得到的值爲3。讓我們假設在下面的簡短分析中,randomElement總是有值3(並且注意randomIndex應該是更合適的名稱)。

copyOfArray的初始大小爲5,允許索引訪問最多在copyOfArray[4]。經過兩次迭代後,copyOfArray的大小爲3(由於刪除了元素copyOfArray.remove(at: randomElement)),這意味着此時copyOfArray[3]會嘗試訪問索引超出範圍。在另一次迭代中,即使copyOfArray[2]超出範圍。由於循環將永遠不會終止,因爲copyOfArray變得更小(朝向空數組[]),因此它被認爲通過索引超出運行時異常而崩潰,同時copyOfArray.remove(at: randomElement)一直嘗試刪除範圍0...3範圍內的索引。

Declaration

mutating func remove(at index: Int) -> Element 

Parameters

index 

The position of the element to remove. indexmust be a valid index of the array.

1

看起來有幾個問題。

首先,通常遠離重複時間是一個好主意。這種範式通常比簡單的while循環要複雜得多。

其次,您的隨機數發生器將遺漏數組的最後一項。

三,你結合陣列和copyOfArray的使用不可預測的方式

試試這個:

var arrayOne : [String] = ["", "", "", "", ""] 

func randomizeArray(array : [String]) -> [String] { 
    var randomizedArray : [String] = [] 
    var copyOfArray : [String] = array 
    while !copyOfArray.isEmpty { 
     let arrayCount : Int = copyOfArray.count 
     let randomElement : Int = Int(arc4random_uniform(UInt32(arrayCount))) 
     let arraySlice : String = copyOfArray[randomElement] 
     randomizedArray.append(arraySlice) 
     copyOfArray.remove(at : randomElement) 
    } 
    return randomizedArray 
} 



print(randomizeArray(array : arrayOne)) 
+0

工作。可能會比這樣做慢,因爲它必須保持計算的隨機數,但它更容易理解,所以從像我這樣的初學程序員的角度來看,它可能會更好。 –

+0

它會慢,因爲它創建一個新的數組而不是交換原始數組中的項目。 – PeejWeej