【问题标题】:Using a computed property to filter an array of objects based on a nested array property使用计算属性根据嵌套数组属性过滤对象数组
【发布时间】:2022-11-20 04:49:47
【问题描述】:

我正在创建一个搜索字段,以允许用户搜索与照片关联的标签,然后仅在我的列表中显示包含该标签的照片。我正在使用计算属性来检查我的 Photo 数组是否包含标签,但标签位于我的 Photo 对象深处的几个属性的嵌套数组中。我需要一些帮助从计算属性中过滤照片数组,以便我的列表使用正确的照片。

我正在尝试使用此计算属性来过滤我的照片:

struct PhotoListView: View {
    let photos: [Photo]
    
    @State private var searchText: String = ""
    
    var filteredPhotos: [Photo] {
        if searchText.count == 0 {
            return photos
        } else {
            return photos.filter { photo in
                return photo.info?.tags.tagContent.filter { $0._content.contains(searchText) }
            }
        }
    }
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(filteredPhotos) { photo in
                    NavigationLink {
                        PhotoDetailView(photo: photo)
                    } label: {
                        PhotoRow(photo: photo)
                    }
                }
            }
            .navigationTitle("Recent Photos")
            .searchable(text: $searchText)
        }
    }
}

上面的尝试导致错误 - Cannot convert value of type '[TagContent]?' to closure result type 'Bool'

class Photo: Decodable, Identifiable {
    let id: String
    let owner: String
    let secret: String
    let title: String
    let server: String
    let farm: Int
    var imageURL: URL?
    var info: PhotoInfo?
}

struct PhotoInfo: Decodable {
    let id: String
    let dateuploaded: String
    let tags: PhotoTags
}

struct PhotoTags: Decodable {
    let tagContent: [TagContent]

    enum CodingKeys: String, CodingKey {
        case tagContent = "tag"
    }
}
struct TagContent: Decodable, Hashable {
    let id: String
    let _content: String
}

使用上面的模型结构,任何人都可以帮我从我的计算属性中过滤 _content 的标签吗?

【问题讨论】:

    标签: arrays swift swiftui decodable


    【解决方案1】:

    过滤器函数需要一个布尔值来确定是否应包含该值。但是现在你的过滤函数只返回内部过滤的集合。检查此集合是否包含任何值。

    return photos.filter { photo in
        !(photo.info?.tags.tagContent.filter { $0._content.contains(searchText) }.isEmpty ?? true)
    }
    

    【讨论】:

      【解决方案2】:

      目前你返回[TagContent]而不是Bool

      filteredPhotos 替换为:

      var filteredPhotos: [Photo] {
          if searchText.count == 0 {
              return photos
          } else {
              return photos.filter { photo in
                  let tagContents = photo.info?.tags.tagContent.filter{ $0._content.contains(searchText) } ?? []
                  
                  return !tagContents.isEmpty
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-11-07
        • 2018-07-06
        • 1970-01-01
        • 2018-12-25
        • 1970-01-01
        • 1970-01-01
        • 2020-02-29
        • 2018-01-16
        • 2016-05-15
        相关资源
        最近更新 更多