Arrays 使用对象筛选嵌套数组
我有一系列的分类。每个类别实例都具有“提供”属性Arrays 使用对象筛选嵌套数组,arrays,swift,filter,Arrays,Swift,Filter,我有一系列的分类。每个类别实例都具有“提供”属性 class Category { var offers : [Offer]? var title : String? var id : Int? } class Offer { var type : String? } //global variable var categories = [ categ1, categ2, ...] 如何按offer.type筛选类别 我已经试过了: return categori
class Category {
var offers : [Offer]?
var title : String?
var id : Int?
}
class Offer {
var type : String?
}
//global variable
var categories = [ categ1, categ2, ...]
如何按offer.type筛选类别
我已经试过了:
return categories.map { (category) -> Category in
let offers = category.offers?.filter { $0.type == myType }
category.offers = offers
return category
}
它可以工作,但在第二次调用函数后,数组变为空。可能是因为报价被改写了
然后我尝试了这个(产生了同样错误的结果):
您可以使用简单易用的
过滤器
(函数式编程),而不是for loop
。
首先筛选类别,然后检查报价是否包含特定类型(使用等于条件)
您应该简单地
过滤所有没有与您的类型相同的优惠的类别。您可以通过以下方式实现这一目标:
过滤所有类别和
在过滤器中
检查当前优惠是否包含myType
代码:
请注意,category.offers?[…]
是可选值,因此??false
如果左侧部分为nil
,则返回false
作为结果
UPD
但我预计类别将只提供type=“A”的优惠。也许我没有准确地描述这个问题
您可以通过创建新的类别
来实现这一点
let filtered = categories.compactMap { category -> Category? in
guard let offers = category.offers?.filter({ $0.type == "A" }) else { return nil }
let other = Category()
other.offers = offers
return other
}
还要注意,我使用的是compactMap
。它允许我使用空或空的选项筛选类别。如果您需要多个筛选器,例如一个模型中的一个字段和嵌套数组中的第二个字段,请
let searchText = "a"
let filteredCategoryList = list.filter { category in
let categoryFilter = category.title?.range(of: searchText, options: .caseInsensitive) != nil
let offerFilter = category.offers?.contains(where: { $0.type?.range(of: searchText, options: .caseInsensitive) != nil
})
return categoryFilter || offerFilter ?? false
}
你是对的,你可能第二次得到一个空数组,因为你在类型上过滤后覆盖了提供。如果您只想根据类型进行筛选,请遵循下面iParesh的回答。但是,对于其他筛选(例如:uitableview中的uisegmented control filters行),如何在不丢失原始数据的情况下进行筛选?请将筛选结果分配给其他变量,并将其用作数据源。不要修改原始类别数组让resultCategories=categories.filter{//Your filter logic}
。当提供的
为零时,此操作将崩溃。我刚刚检查了游戏场中的答案,不幸的是,两者都是错误的。嗨,阿西克。您的代码正确,工作正常,因为这两个类别都至少有一个类型为“A”的报价。如果您尝试将报价3
的类型更改为“C”,您将只看到第一类的报价。请注意,您正在筛选类别,而不是报价。我找到您了。但我预计类别将只提供type=“A”的优惠。若报价不符合该规则,则该类别将不包括在结果数组中。也许我没有准确地描述这个问题。
let filtered = categories.filter { category in
category.offers?.contains(where: { $0.type == myType }) ?? false
}
let filtered = categories.compactMap { category -> Category? in
guard let offers = category.offers?.filter({ $0.type == "A" }) else { return nil }
let other = Category()
other.offers = offers
return other
}
let searchText = "a"
let filteredCategoryList = list.filter { category in
let categoryFilter = category.title?.range(of: searchText, options: .caseInsensitive) != nil
let offerFilter = category.offers?.contains(where: { $0.type?.range(of: searchText, options: .caseInsensitive) != nil
})
return categoryFilter || offerFilter ?? false
}