[英]Filtering UICollectionView depending on filter array
I am having a problem that I can't find a good answer to by myself. 我遇到一个我自己找不到好的答案的问题。
I have an array containing objects that contain information about companies. 我有一个包含对象的数组,这些对象包含有关公司的信息。 Based on this objects I create a collection view where I populate the items from the information inside those objects. 基于此对象,我创建一个集合视图,在其中从这些对象内部的信息中填充项目。
var suppliers = [Suppliers]()
Now I want to add buttons with specific filters. 现在,我想添加带有特定过滤器的按钮。 When pressed on one or more of those buttons the collection view should update with the filters applied. 当按下其中一个或多个按钮时,收集视图应使用已应用的过滤器进行更新。
Therefore I made a few buttons and when pressed I add them to an array containing all the filters. 因此,我做了几个按钮,当我按下按钮时,将它们添加到包含所有过滤器的数组中。
var filters = [Category]()
After that I call a method that should do the filtering and update the collection view. 之后,我调用一个应该进行过滤并更新集合视图的方法。
private func filter()
{
if filters.count > 0 {
suppliers.filter({ ($0.category!).contains(filters)})
}
}
Unfortunately I can't comparison like that, according to xCode. 不幸的是,根据xCode,我无法像那样进行比较。 How do I achieve this filtering correctly? 如何正确实现此过滤?
edit: See the structure of the object below. 编辑:请参见下面的对象结构。
struct Supplier : JSONJoy {
var about: String?
var category: Array<Category>?
var logo: String?
var name: String?
init(_ decoder: JSONDecoder) {
name = decoder["name"].string
logo = decoder["logo"].string
about = decoder["about"].string
if let ctgrys = decoder["category"].array {
category = Array<Category>()
for ctgryDecoder in ctgrys {
category?.append(Category(ctgryDecoder))
}
}
}
struct Category : JSONJoy {
var id: Int?
var name: String?
init(_ decoder: JSONDecoder) {
id = decoder["id"].integer
name = decoder["name"].string
}
}
1) $0.category!
1) $0.category!
is [Category]
type. 是[Category]
类型。 And you have [Category].contains
call which requires (Category) throws -> Bool
parameter, but in your case it is filters
variable with [Category]
type 并且您有[Category].contains
调用,它要求(Category) throws -> Bool
参数,但是在您的情况下,它是[Category]
类型的filters
变量
2) You never apply your filter result 2)您永远不会套用筛选结果
This is possible implementation of your filtering, if I understand your needs correctly: 如果我正确理解了您的需求,则可以执行您的过滤:
private func filter() -> [Supplier] {
if filters.count > 0 {
return suppliers.filter { supplier in
return supplier.category?.contains { supplierCategory in
return filters.contains {
return supplierCategory.id == $0.id
}
} ?? false
}
} else {
return suppliers
}
}
We need to fix a couple of details that are going to make our lifes easier :) 我们需要修复一些细节,这将使我们的生活更轻松:)
struct Category: JSONJoy, Equatable, Hashable {
var id: Int?
var name: String?
init(_ decoder: JSONDecoder) {
id = decoder["id"].integer
name = decoder["name"].string
}
var hashValue: Int { get { return id?.hashValue ?? 0 } }
}
func ==(left:Category, right:Category) -> Bool {
return left.id == right.id && left.name == right.name
}
struct Supplier: JSONJoy {
var about: String?
var category = [Category]() // <- I changed this
var logo: String?
var name: String?
init(_ decoder: JSONDecoder) {
name = decoder["name"].string
logo = decoder["logo"].string
about = decoder["about"].string
if let ctgrys = decoder["category"].array {
category = Array<Category>()
for ctgryDecoder in ctgrys {
category.append(Category(ctgryDecoder))
}
}
}
}
You have your list of suppliers and your list of filters 您有供应商清单和过滤器清单
var suppliers = [Supplier]()
var filters = [Category]()
Now I am not sure about how you want to filter suppliers
. 现在我不确定如何过滤suppliers
。
However IF you want all the suppliers having at least a filter listed in filters
then 但是, 如果您希望所有供应商在filters
中至少列出一个过滤 filters
则
let requiredFilters = Set(filters)
let supplierWithAtLeastOneRequiredFilter = suppliers.filter { !Set($0.category).intersect(requiredFilters).isEmpty }
On the other hand IF you want all the suppliers having all the filters listed in filters
then 另一方面, 如果您希望所有供应商的过滤器中列出所有过滤 filters
则
let requiredFilters = Set(filters)
let supplierWithEveryRequiredFilter = suppliers.filter { Set($0.category).isSupersetOf(filters) }
Assuming filtered
is the filtered array
of Supplier
. 假设已filtered
是Supplier
的已过滤array
。 and AllData
is the full array of Supplier
. AllData
是Supplier
的完整数组。 And you want to filter only items which contain the word "ao"
at their name
property. 而且,您只想过滤name
属性中包含单词"ao"
项目。
filtered = AllData.filter {
$0.name.rangeOfString("ao", options: .CaseInsensitiveSearch) != nil
}
if(filtered.count == 0){
//No Results -
} else {
//There are results - update the tableView data source accordingly
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.