使用Swift中的值数组按属性过滤对象数组

Jon*_*aul 5 arrays contains filter swift

使用值数组过滤基于其中一个属性的对象数组的最有效方法是什么?我可以遍历这些项目,但我不禁想到使用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})})
Run Code Online (Sandbox Code Playgroud)

Jon*_*aul 13

这是我在操场上工作的原因,为什么这不好?

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"}]
Run Code Online (Sandbox Code Playgroud)


Vik*_*ica 6

你也可以使用类似的东西

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

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


Ars*_*sen 3

我建议您按作者制作书籍索引:

let book = Book(author: "Arsen")
let bookIndex = [book.author: [book]]
Run Code Online (Sandbox Code Playgroud)

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

bookIndex["Arsen"] // => [Books]
Run Code Online (Sandbox Code Playgroud)

对于多个作者:

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

results
Run Code Online (Sandbox Code Playgroud)