Scala镜头用于收集参数
发布时间:2020-12-16 09:54:33 所属栏目:安全 来源:网络整理
导读:使用镜头更新集合中元素的最佳方法是什么?例如: case class Ingredient(name: String,quantity: Int)case class Recipe(val ingredients: List[Ingredient]) 如果我想使用镜片来创建一个单一成分的数量改变的新配方,那么最好的方法是什么? 我尝试过的方法
使用镜头更新集合中元素的最佳方法是什么?例如:
case class Ingredient(name: String,quantity: Int) case class Recipe(val ingredients: List[Ingredient]) 如果我想使用镜片来创建一个单一成分的数量改变的新配方,那么最好的方法是什么? 我尝试过的方法是即时创建镜头:镜头[列表[成分],成分].虽然这感觉有点笨重: case class Recipe(val ingredients: List[Ingredient]) { import Recipe._ def changeIngredientQuantity(ingredientName: String,newQuantity: Int) = { val lens = ingredientsLens >=> ingredientLens(ingredientName) >=> Ingredient.quantityLens lens.set(this,newQuantity) } } object Recipe { val ingredientsLens = Lens.lensu[Recipe,List[Ingredient]]( (r,i) => r.copy(ingredients = i),r => r.ingredients ) def ingredientLens(name: String) = Lens.lensu[List[Ingredient],Ingredient]( (is,i) => is.map (x => if (x.name == name) i else x),is => is.find(i => i.name == name).get ) } case class Ingredient(name: String,quantity: Int) object Ingredient { val quantityLens = Lens.lensu[Ingredient,Int]( (i,q) => i.copy(quantity = q),i => i.quantity ) } 解决方法
您无法在给定索引处的List [T]和T之间创建镜头,因为镜头需要您关注的对象始终存在.但是,如果在List或另一个集合中查找,索引中可能没有元素.
然而,您可以使用Traversal,一种专注于0到多个元素的镜头.使用Monocle,您将使用索引函数创建从List到特定索引处的元素的遍历: import monocle.SimpleLens import monocle.syntax.lens._ // to use |-> and |->> instead of composeLens,composeTraversal import monocle.functions.Index._ // to use index Traversal // monocle also provides a macro to simplify lens creation val ingredientsLens = SimpleLens[Recipe,List[Ingredient]](_.ingredients,(recipe,newIngredients) => recipe.copy(ingredients = newIngredients)) val quantityLens = SimpleLens[Ingredient,Int](_.quantity,(ingredient,newQuantity) => ingredient.copy(quantity = newQuantity)) val applePie = Receipe(List(Ingredient("apple",3),Ingredient("egg",2),...)) applePie |-> ingredientsLens |->> index(0) headOption // Some(Ingredient("apple",3)) applePie |-> ingredientsLens |->> index(999) headOption // None applePie |-> ingredientsLens |->> index(0) |->> quantityLens headOption // 3 applePie |-> ingredientsLens |->> index(0) |->> quantityLens set 5 // Receipe(List(Ingredient("apple",5),...)) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |