随机化一个数组

时间:2016-11-01 19:23:31

标签: arrays swift swift3

我需要为我试图在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 个答案:

答案 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 必须有效   数组的索引