SwiftUI ForEach,条件并显示许多结果中的一个

SwiftUI ForEach, conditionals and showing one result of many

我有一个有趣的循环和条件问题,但我无法解决。

struct ForEachLoopTesting: View {
    
    let start = ["a", "b", "c", "a"]
    let this = ["a", "b"]
    
    var body: some View {
        VStack {
            ForEach(start, id:\.self) { test1 in
                ForEach(start, id:\.self) { test2 in
                    if [test1, test2] == this {
                        Text("true") // this prints twice…how can I get to print only once?
                    }
                }
            }
        }
    }
}

关于如何显示满足条件的多个结果中的第一个结果有什么想法吗?或者也许我处理这个问题有更好的方法?

您不应该在视图主体内管理它。相反,将逻辑留给支持函数并让 SwiftUI 在屏幕上呈现最终结果可能会更容易。

下面的示例将逻辑与视图的主体分开:

struct ForEachLoopTesting: View {
    
    let start = ["a", "b", "c", "a"]
    let this = ["a", "b"]
    
    // Supporting function
    private var merged: [[String]] {
        var merged = [[String]]()
        
        start.forEach { test1 in
            start.forEach { test2 in
                let item = [test1, test2]
                
                // Check for both: the condition and that
                // the pair is not yet included in the array
                if item == this && !merged.contains(item) {
                    merged.append([test1, test2])
                }
            }
        }
        return merged
    }

    var body: some View {
        VStack {
            
            // Read and show the final result
            ForEach(merged, id:\.self) { item in
                HStack {
                    Text(item[0])
                    Text(item[1])
                    Text("true")
                }
            }
        }
    }
}

您可以尝试类似这种方法,而不使用 ForEach 循环(因为它们要求条目是唯一的):

struct ForEachLoopTesting: View {
    
    let start = ["a", "b", "c", "a"]
    let this = ["a", "b"]
    
    var body: some View {
        if startContains(this) {
            Text("yes start contains this")
        } else {
            Text("no start does not contain this")
        }
    }
    
    func startContains(_ this: [String]) -> Bool {
        var result = false
        outerLoop: for test1 in start {
          for test2 in start {
             if ([test1, test2] == this) {
                result = true
                break outerLoop
             }
          }
      }
      return result
    }

// alternative
func startContains2(_ this: [String]) -> Bool {
    for test in this {
        if !start.contains(test) {
            return false
        }
    }
    return true
}
    
}