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

时间:2015-10-22 19:18:32

标签: arrays swift filter contains

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

3 个答案:

答案 0 :(得分: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"}]

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

你也可以使用像

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

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