【问题标题】:Filter an array of objects by property, using an array of values in Swift使用 Swift 中的值数组按属性过滤对象数组
【发布时间】:2016-01-22 04:49:05
【问题描述】:

使用值数组根据对象的一个​​属性过滤对象数组的最有效方法是什么?我可以遍历这些项目,但我不禁想到使用 Array.filter 和 Array.contains 有一种非常有效的方法——我只是不够精通 Swift,无法将这些部分组合在一起。

例如,如果我有一个包含 Book 对象的数组,每个对象都有一个 String author 属性,我将如何过滤它以仅显示 John Smith、Arthur Price 或 David Jones 的书籍?

类似的东西:

Class Book {
    var author : String = String()
}

var books : Array = [Book]()
//books added elsewhere

let authors = ["John Smith", "Arthur Price", "David Jones"]

let filteredBooks = books.filter({authors.contains({($0 as Book).author})})

【问题讨论】:

  • 您需要最简单的方法还是最有效的方法?如果最有效,那么例如您需要首先准备数据并将数组转换为带有键的字典 - 搜索字段和值 - Book 对象。执行此操作后,您的搜索将是最有效的
  • @Alex,你会如何将该方法应用于我刚刚添加的命令?
  • 您正在使用数组,在这种情况下,搜索可能不会尽可能快,要使其尽可能快,您需要使用字典。如果您需要快速搜索,请参阅下面来自 Arsen 的答案,我的意思有一个示例

标签: arrays swift filter contains


【解决方案1】:

你也可以使用类似的东西

let authorsAndBooks = authors.map { (authorName) -> (String, [Book]) in (authorName, allBooks.filter({ $0.author == authorName })) }

这将是一个元组数组,第一个元素是作者姓名,第二个元素是他的书籍数组,以防作者写了多本书。

【讨论】:

  • 你每次都会多次获得相同的 authorName 和对应的 book 数组。
【解决方案2】:

这就是我在操场上工作的东西,有什么不好的理由吗?

class Book {
    var author = String()

    init(author:String){
        self.author = author
    }
}

var allBooks: [Book] = []

allBooks.append(Book(author: "John Smith"))
allBooks.append(Book(author: "Arthur Price"))
allBooks.append(Book(author: "David Jones"))
allBooks.append(Book(author: "Somebody Else"))

let authors = ["Arthur Price", "David Jones"]

let filteredBooks = allBooks.filter({authors.contains($0.author)})

filteredBooks       // [{author "Arthur Price"}, {author "David Jones"}]

【讨论】:

    【解决方案3】:

    我建议您按作者对书籍进行索引:

    let book = Book(author: "Arsen")
    let bookIndex = [book.author: [book]]
    

    现在您可以快速访问按作者过滤的图书:

    bookIndex["Arsen"] // => [Books]
    

    对于多个作者:

    var results = [Book]()
    for author in authors {
        if let books = bookIndex[author] {
            results += books
        }
    }
    
    results
    

    【讨论】:

    • 这看起来很有趣,但是如何使用索引来过滤多个值?
    • @Jon-Paul 查看更新。我认为它可以用mapflatmap 以单行样式编写,但仍然是非常有效的方式
    • 谢谢 - 这会比我建议的使用数组更快吗?
    • 明确地说,我并不需要尽可能快。我只是对在学习 Swift 时使用最好的设计模式感兴趣。 :)
    猜你喜欢
    • 2019-05-04
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多