在swift中是否可以循环并随机选择和删除数组中的项?

83qze16e  于 2023-10-15  发布在  Swift
关注(0)|答案(1)|浏览(103)

我收到一个错误:
Swift/ContiguousArrayBuffer.swift:600:致命错误:索引超出范围

func buildShipYard(random: Int) {
    guard let opponentGold = camera.opponentResource.component(ofType: GoldComponent.self), let opponentTech = camera.opponentResource.component(ofType: TechLevelComponent.self)?.techLevel else { return }
    
    if opponentGold.gold >= prices.shipYardPrice {
        if opponentTech >= techRequirements.shipYardRequirement {
            opponentGold.spendGold(amount: prices.shipYardPrice)
            let selectedLocation = locations[random]
            selectedLocation.locationMenu.locationSelected = true
            let locationToBuildOn = locations.first(where: { $0.locationMenu.locationSelected })
            locationToBuildOn?.createShipYard(base: base)
            selectedLocation.locationMenu.locationSelected = false
            
            if let index = locations.firstIndex(where: { $0 == selectedLocation }) {
                locations.remove(at: index)
                print(locations.count)
            }
        }
    }
}

第二次运行时,错误发生在let selectedLocation = locations[random]行上
下面是我调用函数的地方:

for location in playerBase!.locations {
     if location.tavernBuilding {
          buildShipYard(random: mersenne.nextInt(upperBound: base.locations.count))
     } }

我每次都从数组中删除特定的索引,所以后面的索引每次都应该在边界内。

zaq34kh6

zaq34kh61#

你调用buildShipYard(random: mersenne.nextInt(upperBound: base.locations.count)),虽然你没有包含nextInt的代码,但如果它从一个上限为locations.count的封闭范围中随机选择一个值,你可能会忘记count是1索引的,而数组是0索引的,你需要使用count-1
作为防御措施,您可以在buildShipYard方法开始时检查random是否是有效索引,然后您可以简单地执行以下操作:

locations.remove(at: index)

而不是你目前所拥有的过于复杂和低效的方法。

相关问题