我需要传递元组数组作为一个函数的参数,该函数从数组中选择随机元组,同时考虑另外两个参数。)此函数返回索引,我将使用该索引来播放此随机文件。此函数位于类fileManager()
中class fileManager {
var drums = [
("drum", "drum", 8, 2, false, 153, "C", 1),
("drum", "drum2", 6, 3, false, 153, "C", 1),
("drum", "drum3", 8, 2, false, 153, "C", 1),
("drum", "drum4", 4, 2, false, 153, "C", 1),
("drum", "drum5", 8, 1, false, 153, "C", 1) ]
var piano = [
("piano", "piano", 8, 2, false, 153, "C", 1),
("piano", "piano2", 8, 3, false, 153, "C", 1),
("piano", "piano3", 8, 1, false, 153, "C", 1)
]
//instrumentArray will be any instrument, Strength - we need to find, KeyNote - we need to find in Array.
func randomizeTheNextInstrument (instrumentArrayInput: [(String,String,Int,Int,Bool,Int,String, Int)], Strength: Int , KeyNote: String) -> Int {
var instrumentArray = instrumentArrayInput
var indexInstrument: Int!
for index in 0...instrumentArray.count {
if instrumentArray[index].4 == true { //check if played
instrumentArray.removeAtIndex(index)
}
if instrumentArray[index].6 != KeyNote { // check keyNote
instrumentArray.removeAtIndex(index)
}
if instrumentArray[index].3 != Strength { // check strength
instrumentArray.removeAtIndex(index)
}
}
var indexToChoose: Int = Int(arc4random_uniform(UInt32(instrumentArray.count)))
for index in 0...instrumentArrayInput.count {
if instrumentArrayInput[index].1 == instrumentArray[indexToChoose].1 { // finds what one in ArrayInpu equals the randomized one in Array that chosen
indexInstrument = index
}
}
return indexInstrument
}
}
但是当我通过这样做从另一个类调用该函数时。
indexToPlay = Int(fileManager().randomizeTheNextInstrument(fileManager().drums, Strength: drumStrength, KeyNote: "C"))
它给了我致命的错误:“数组索引超出范围 (lldb)“它告诉我数组instrumentArrayInput有5个值,但值是'none',instrumentArray有3个值,但值是'none'。接下来,看起来很奇怪的是indexToChoose = 140734791422096。它还写道我的字符串EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0):
if instrumentArray[index].4 == true {
我做错了什么?
答案 0 :(得分:0)
此:
for index in 0...instrumentArray.count {
应该是:
for index in 0..<instrumentArray.count {
由于数组是零索引的,因此最后一个有效索引比数组中的项数少一个。
Anthony实际上指出了你的函数的几个问题,所有这些问题都可以通过使用内置的过滤器函数来解决:
instrumentArray = instrumentArrayInput.filter {
return !$0.4 && $0.6 == KeyNote && $0.3 == Strength
}
替换整个for循环。
为了解决更多问题,我会选择这样的东西,虽然有更多建议改变(比如使用结构或类而不是元组):
class FileManager {
typealias Instrument = (String,String,Int,Int,Bool,Int,String, Int)
var drums : [Instrument] = [
("drum", "drum", 8, 2, false, 153, "C", 1),
("drum", "drum2", 6, 3, false, 153, "C", 1),
("drum", "drum3", 8, 2, false, 153, "C", 1),
("drum", "drum4", 4, 2, false, 153, "C", 1),
("drum", "drum5", 8, 1, false, 153, "C", 1)
]
var piano : [Instrument] = [
("piano", "piano", 8, 2, false, 153, "C", 1),
("piano", "piano2", 8, 3, false, 153, "C", 1),
("piano", "piano3", 8, 1, false, 153, "C", 1)
]
func randomizeTheNextInstrument(instrumentArrayInput: [Instrument], Strength: Int, KeyNote: String) -> Int? {
let instrumentArray = instrumentArrayInput.filter {
return !$0.4 && $0.6 == KeyNote && $0.3 == Strength
}
if instrumentArray.count <= 0 {
return nil
}
let indexToChoose: Int = Int(arc4random_uniform(UInt32(instrumentArray.count - 1)))
let name = instrumentArray[indexToChoose].1
for index in 0 ..< instrumentArrayInput.count {
if name == instrumentArrayInput[index].1 {
return index
}
}
return nil
}
}
let fileManager = FileManager()
if let indexToPlay = fileManager.randomizeTheNextInstrument(fileManager.drums, Strength: 3, KeyNote: "C") {
println("\(fileManager.drums[indexToPlay])")
fileManager.drums[indexToPlay].4 = true
}
if let indexToPlay = fileManager.randomizeTheNextInstrument(fileManager.drums, Strength: 3, KeyNote: "C") {
println("\(fileManager.drums[indexToPlay])")
fileManager.drums[indexToPlay].4 = true
}
答案 1 :(得分:0)
在循环中,您要从数组中删除元素,因此其长度会减小。
此外,还有3个独立的if
语句,这些语句最多可以在同一次迭代中删除3个元素。我会在每个break
正文中添加if
(跳过当前的迭代并移到下一个),或者将它们重新组织为if/else if/else
。
但是为了修复异常,我建议添加元素以保留在第二个数组中,或者仅仅是它们的索引,而不是从数组中删除元素。
最后,请注意循环错误,应该是for index in 0..<instrumentArray.count
而不是for index in 0...instrumentArray.count
<强>更新强>
如果你仍然需要保留从数组中删除元素的最初想法,那么你应该修改循环以反向顺序遍历它,并使用if/elseif
而不是独立的if
。例如:
for var index = instrumentArray.count - 1; index >= 0; --index {
if instrumentArray[index].4 == true { //check if played
instrumentArray.removeAtIndex(index)
} else if instrumentArray[index].6 != KeyNote { // check keyNote
instrumentArray.removeAtIndex(index)
} else if instrumentArray[index].3 != Strength { // check strength
instrumentArray.removeAtIndex(index)
}
}
需要以相反的顺序循环,因为当一个元素被移除时,它后面的所有元素都会向后移动一个位置,而前面的所有元素都不会受到影响。通过这种方式,您可以确保所有仍处理的元素都不会更改其索引。