【问题标题】:How do I filter on an array of objects in Swift?如何过滤 Swift 中的对象数组?
【发布时间】:2019-02-27 11:45:05
【问题描述】:

您好,我有一个 Book 类型对象数组,我正在尝试返回由 tags 属性过滤的所有 Books。例如

var books = [

(title = "The Da Vinci Code", tags = "Religion, Mystery, Europe"), 
(title = "The Girl With the Dragon Tatoo", tags = "Psychology, Mystery, Thriller"), 
(title = "Freakonomics", tags = "Economics, non-fiction, Psychology")

}]

我想找到与标签Psychology(title = "The Girl With the Dragon Tatoo", tag = "Psychology, Mystery, Thriller")(title = "Freakonomics", tags = "Economics, non-fiction, Psychology") 关联的书籍,我该怎么做?

【问题讨论】:

  • 从使用合适的数据模型开始。定义一个带有标题属性的结构体和一个字符串数组的标签属性。使用元组并将标签作为单个字符串是一种糟糕的数据模型选择,并且会使您的所有任务变得更加困难。

标签: swift filter


【解决方案1】:

我认为这对于没有错误输入的情况更有用。

books.filter( { $0.tag.range(of: searchText, options: .caseInsensitive) != nil}

【讨论】:

    【解决方案2】:

    将书籍表示为一个元组数组,带有命名参数 title 和 tags 分别表示书名和标签。

    let books:[(title:String, tags:String)] = [
    
        (title: "The Da Vinci Code", tags: "Religion, Mystery, Europe"),
        (title: "The Girl With the Dragon Tatoo", tags: "Psychology, Mystery, Thriller"),
        (title: "Freakonomics", tags: "Economics, non-fiction, Psychology")
    
    ]
    

    你要搜索标签Psychology

    let searchedTag = "Psychology"
    

    我们可以使用filter函数过滤出books数组中只包含我们要查找的标签的项目。

    let searchedBooks = books.filter{ $0.tags.split(separator: ",").map{ return $0.trimmingCharacters(in: .whitespaces) }.contains( searchedTag ) }
    
    print(searchedBooks)
    

    在过滤器方法中,我们使用split(separator: Character) 方法从书籍标签创建了一个标签项数组。接下来,使用map 函数,我们从每个标签中删除前导和尾随空格。最后,使用.contains(element) 方法,我们测试我们要查找的标签是否在这个数组中。仅返回通过此测试的元组,其他元组将被过滤掉。

    结果是:

    [(标题:《龙纹身的女孩》,标签:《心理学,神秘,惊悚》), (title: "Freakonomics", tags: "Economics, non-fiction, Psychology")]

    【讨论】:

      【解决方案3】:

      所以我很快就做了这个来帮忙,如果有人可以改进那很好,我只是想帮忙。

      我为书做了一个结构

      struct Book {
          let title: String
          let tag: [String]
      }
      

      创建了一个数组

      var books: [Book] = []
      

      哪个是空的。

      我为每本书创建了一个新对象并附加到书籍

      let dv = Book(title: "The Da Vinci Code", tag: ["Religion","Mystery", "Europe"])
      books.append(dv)
      let gdt = Book(title: "The Girl With the Dragon Tatoo", tag: ["Psychology","Mystery", "Thriller"])
      books.append(gdt)
      let fn = Book(title: "Freakonomics", tag: ["Economics","non-fiction", "Psychology"])
      books.append(fn)
      

      所以你现在在 books 数组中有三个对象。 尝试检查

      print (books.count)
      

      现在您要过滤心理学书籍。 我过滤了心理学标签的数组 - 过滤器适合你吗?

      let filtered = books.filter{ $0.tag.contains("Psychology") } 
      filtered.forEach { print($0) }
      

      用你的两本心理学书打印对象

      Book(title: 《龙纹身的女孩》, tag: [《心理学》, “悬疑”、“惊悚”])

      Book(title: "Freakonomics", tag: ["Economics", "non-fiction", “心理学”])

      【讨论】:

      • 不要忘记 Swift 它是一种类型推断语言,99% 的时间都不需要显式声明您的类型。顺便说一句,您应该将结构属性声明为常量
      • 我相信他是说我们可以使用 let dv = Book(title: "The Da Vinci Code", tag: ["Religion","Mystery", "Europe"]) 的形式为每个书
      • struct Book { let title: String let tag: [String] }
      • 请注意,您的filter count == 1 非常糟糕,即使它在第一个索引处找到元素,它也会迭代整个数组。将其更改为books.filter{ $0.tag.contains( "Psychology")},这将提供一个提前退出,以防匹配它
      • 谢谢,这是我作为开发人员工作 14 个月以来收到的更多反馈
      猜你喜欢
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-08
      • 2019-12-13
      相关资源
      最近更新 更多