我有两个班级“Receipe”和“Incredient”。一个recipe可以有一个令人难以置信的列表。现在,我希望当我传递一个令人难以置信的清单时,我应该收到所有收据,其中包含令人难以置信的收据。这就是我所拥有的:
如何根据传入的难以置信的人过滤收据。
class Recipe {
var name :String!
var incredients :[Incredient]!
init(name :String, incredients :[Incredient]) {
self.name = name
self.incredients = incredients
}
}
class Incredient {
var name :String!
init(name :String) {
self.name = name
}
}
var incredientsToSearchFor = [Incredient(name:"Salt"),Incredient(name :"Sugar")]
var receipe1 = Recipe(name: "Receipe 1", incredients: [Incredient(name: "Salt"),Incredient(name :"Pepper"),Incredient(name :"Water"),Incredient(name :"Sugar")])
var receipe2 = Recipe(name: "Receipe 2", incredients: [Incredient(name: "Salt"),Incredient(name :"Pepper"),Incredient(name :"Water"),Incredient(name :"Sugar")])
var receipe3 = Recipe(name: "Receipe 3", incredients: [Incredient(name :"Pepper"),Incredient(name :"Water"),Incredient(name :"Sugar")])
var receipies = [receipe1,receipe2,receipe3] // list of all the recipies
func getRecipiesByIncrediants(incredients :[Incredient]) -> [Recipe] {
// WHAT TO DO HERE
return nil
}
let matchedRecipies = getRecipiesByIncrediants(incredientsToSearchFor)
答案 0 :(得分:1)
有些事情需要改变。
首先,这些是数据模型,因此它们应该是struct
类型而不是class
。这允许您删除初始化程序和选项:
struct Recipe : Equatable {
let name: String
let ingredients: [Ingredient]
}
struct Ingredient : Equatable {
let name : String
}
您会注意到我也制作了Equatable
。这样您就可以使用contains
在数组中查找它们。没有它,contains
不知道这些类型中的两个是否相等。
要符合Equatable,只需添加==
方法:
func ==(lhs: Ingredient, rhs: Ingredient) -> Bool {
return lhs.name == rhs.name
}
func ==(lhs: Recipe, rhs: Recipe) -> Bool {
return lhs.name == rhs.name && lhs.ingredients == rhs.ingredients
}
创建数据大致相同。我修正了一些拼写错误并将var
更改为let
,因为这些值不会改变:
let ingredientsToSearchFor = [Ingredient(name:"Salt"), Ingredient(name :"Sugar")]
let recipe1 = Recipe(name: "Recipe 1", ingredients: [Ingredient(name: "Salt"), Ingredient(name :"Pepper"), Ingredient(name :"Water"), Ingredient(name :"Sugar")])
let recipe2 = Recipe(name: "Recipe 2", ingredients: [Ingredient(name: "Salt"), Ingredient(name :"Pepper"), Ingredient(name :"Water"), Ingredient(name :"Sugar")])
let recipe3 = Recipe(name: "Recipe 3", ingredients: [Ingredient(name :"Pepper"), Ingredient(name :"Water"), Ingredient(name :"Sugar")])
let recipes = [recipe1, recipe2, recipe3] // list of all the recipes
现在进行过滤。这是更有效的方法,但为了便于阅读,您可以使用filter
和reduce
:
func getRecipesByIngredients(incredients :[Ingredient]) -> [Recipe] {
return recipes.filter { recipe in
incredients.reduce(true) { currentValue, ingredient in
return currentValue && (recipe.ingredients.contains(ingredient))
}
}
}
filter
返回一个新数组,其中只包含块返回true
的元素。 reduce
将整个数组合并为一个值(在本例中为true
或false
)。因此,我们遍历每个配方,并检查是否所有指定成分都在其中。
调用方法:
let matchedRecipes = getRecipesByIngredients(ingredientsToSearchFor)
这会返回食谱1和2,因为它们都含有盐和糖。
如果您想要含有盐或糖的食谱,请使用reduce(false)
并将&&
更改为||
。