【问题标题】:Filter Logic in SwiftUI - Apple TutorialSwiftUI 中的过滤逻辑 - Apple 教程
【发布时间】:2021-08-11 03:48:34
【问题描述】:

我正在学习 Landmarks SwiftUI 教程 https://developer.apple.com/tutorials/swiftui/handling-user-input。我对在

中使用逻辑运算符感到困惑
landmarks.filter { landmark in
            (!showFavoritesOnly || landmark.isFavorite)
        }

我试图了解此逻辑在返回过滤后的地标时的工作原理。我很确定!运算符反转 showFavoritesOnly 操作数和 || landmark.isFavorite 上的运算符使声明为真,如果任何一方在闭包中为真,但由于某种原因,就返回的内容而言,目前应该发生的事情让我无法理解。如果有人能澄清我将非常感激。

这是上下文文件:

 import SwiftUI
    
    struct LandmarkList: View {
        @State private var showFavoritesOnly = false
        
        var filteredLandmarks: [Landmark] {
            landmarks.filter { landmark in
                (!showFavoritesOnly || landmark.isFavorite)
            }
        }
        
        var body: some View {
            NavigationView {
                List(filteredLandmarks)
                    { landmark in
                    NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
                        LandmarkRow(landmark: landmark)
                    }
                }
                .navigationTitle("Landmarks")
            }
        }
    }
    
    struct LandmarkList_Previews: PreviewProvider {
        static var previews: some View {
                LandmarkList()
        }
    }

【问题讨论】:

    标签: swiftui logical-operators


    【解决方案1】:

    我很确定!运算符反转 showFavoritesOnly 操作数和 ||如果任一方为真,则 landmark.isFavorite 上的运算符使语句为真

    你完全正确。

    但出于某种原因,这就返回的内容而言应该发生的事情目前让我无法理解。

    filter(_:) 方法允许您过滤一个数组(删除不满足条件的元素)。

    它需要一个闭包,isIncluded。这个闭包对数组中的每个元素调用一次,并将当前元素传递给参数:

                   /// ↓ the current element in the array
    landmarks.filter { landmark in }
    

    这个闭包必须返回一个Bool,它表示是否应该保留该元素。

    • 所以如果它返回true,则表示保留该元素
    • 如果false,则移除该元素

    在您的实现中,您将保留 showFavoritesOnly 为 false 或 isFavorite 为 true 的元素。

    landmarks.filter { landmark in
        (!showFavoritesOnly || landmark.isFavorite) /// return the Bool
    }
    

    也许你对为什么没有返回声明感到困惑......

    landmarks.filter { landmark in
        return (!showFavoritesOnly || landmark.isFavorite)
    }
    

    原因是当你只有一个表达式时return 关键字是可选的。如果你做了类似的事情:

    landmarks.filter { landmark in
        let elementShouldBeKept = (!showFavoritesOnly || landmark.isFavorite)
        return elementShouldBeKept
    }
    

    ...那么你需要return

    【讨论】:

    • @JamesH ! 运算符影响showFavoritesOnly。它检查它是真还是假,然后评估相反的结果。 showFavoritesOnly 永远不会被修改。
    • @shaze 我想我明白了。这是一个很好的答案。所以,如果 showFavoritesOnly 被初始化为 false !运算符将其反转以在闭包中进行评估,因此无需在 || 之后检查 landmark.isFavorite因为闭包已经确定闭包是真的。因此将返回 [Landmark] 数组中的每个元素。这就是我从中得到的,在某种程度上。
    • @JamesH 完全正确!如果showFavoritesOnly 为真,那么!showFavoritesOnly 将为假,因此由landmark.isFavorite 决定是否保留该元素。
    【解决方案2】:

    !showFavoritesOnly 等同于说if (showFavoritesOnly == false) return true

    因此,在评估过滤列表时: 如果!showFavoritesOnly,它不需要评估语句的其余部分,因为返回了“真”,并且元素被放置在要显示的列表中(即在这种情况下,所有元素的未过滤列表,作为每个元素将评估为showFavoritesOnly == false)。

    但是,一旦showFavoritesOnly 为真,计算机就会评估该语句的下半部分。

    我制作了一个流程图,帮助我将这个概念形象化:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多