Arrays 在SwiftUI中初始化可变结构
我有一种情况,要求用户记忆字符串数组。当从数组中随机选择一个元素进行提示时,要求用户命名三个相邻的元素。(在现实生活中,这一切都与音符有关——为了简单起见,我将问题归结为字符串和数组)。有两个复杂因素。首先,代码应该避免在一行中两次向用户显示相同的提示元素。其次,用户可以随时在命名显示在提示元素之前的元素和显示在提示元素之后的元素之间进行切换(音乐上,这对应于升序或降序)Arrays 在SwiftUI中初始化可变结构,arrays,view,swiftui,initialization,Arrays,View,Swiftui,Initialization,我有一种情况,要求用户记忆字符串数组。当从数组中随机选择一个元素进行提示时,要求用户命名三个相邻的元素。(在现实生活中,这一切都与音符有关——为了简单起见,我将问题归结为字符串和数组)。有两个复杂因素。首先,代码应该避免在一行中两次向用户显示相同的提示元素。其次,用户可以随时在命名显示在提示元素之前的元素和显示在提示元素之后的元素之间进行切换(音乐上,这对应于升序或降序) StringChooser结构包含字符串数组,并提供一个函数来返回随机选择的字符串。它还保存随机选择的字符串的索引,以便我以
StringChooser
结构包含字符串数组,并提供一个函数来返回随机选择的字符串。它还保存随机选择的字符串的索引,以便我以后可以使用该索引查找相邻元素
struct StringChooser {
// MARK: API
var myStrings: [ String ]
var lastChosenStringIndex = Int.max
// MARK: Methods
mutating func getRandomString() -> String {
// pick random string that is NOT the same as previously
// picked element
var randomIndex: Int
repeat {
randomIndex = Int.random(in: 0 ..< myStrings.count )
} while randomIndex == lastChosenStringIndex
// save the index for the picked element so that
// later we can find the adjacent elements
lastChosenStringIndex = randomIndex // supposed SAVE!
return myStrings[ randomIndex ]
}
}
[其他方法:如果我尝试使用init()初始化StringChooser实例,也会产生相同的结果。在模拟器中运行时,会出现运行时警告,指出在视图外部更改状态变量可能会导致问题。]理想情况下,避免变异值类型
StringChooser
有一个状态,在我看来,它更适合作为一个类。还有let randomIndex=myStrings.index.randomElement()
而不是重复/while
循环。您好,新开发人员!repeat/while用于避免在一行中两次或多次显示相同的提示字符串。对不起,我没说清楚。尽管如此,还是要感谢index.randomElement()提示。这很酷,但当我(稍后)需要查找与prompt-element相邻的三个元素时,这会使任务复杂化。哦,关于repeat/while
。。。哪一部分使任务复杂化?使其成为引用类型?据我所知,“.randomElement”函数返回实际元素(而不是索引)。由于数组不一定是经过排序的,所以问题变成了如何有效地查找相邻元素。如果索引可用,则不太复杂。arr.randomElement()
返回数组的元素arr.index.randomElement()
返回索引数组的元素,即索引。然后,您可以使用.index(后:)
和.index(前:)
查找相邻的索引
struct ContentView: View {
@Binding var stringChooser: StringChooser
@State private var chosenString = "not initialized"
var body: some View {
VStack {
Spacer()
Text( "Random String: \( stringChooser.getRandomString() )." )
Spacer()
Text("Index of chosen string: '\( stringChooser.lastChosenStringIndex )'.")
Spacer()
Button( "Again" )
{
chosenString =
stringChooser.getRandomString()
}
Spacer()
}
}
}