我需要为我试图在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打印函数时,它表示"致命错误:索引超出范围。"有没有想过为什么会这样?
答案 0 :(得分:2)
看起来有一些问题。
首先,通常远离重复时间是个好主意。这个范例通常比简单的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))
答案 1 :(得分:1)
当我尝试使用数组1打印函数时,它会说"致命 错误:索引超出范围。" 为什么会发生这种情况?
我会回答这个问题。
属性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
变小(朝向空数组,[]
)时,它迟早会被索引超出边界运行时异常而崩溃,同时{{ 1}}一直试图删除copyOfArray.remove(at: randomElement)
范围内的索引。
<强>声明强>
0...3
<强>参数强>
mutating func remove(at index: Int) -> Element
要删除的元素的位置。
index
必须有效 数组的索引 。