Was ist der beste Weg, um ein Element in einer Sammlung mit Linsen zu aktualisieren? Zum Beispiel:Scala-Objektiv für Sammlungs-Parameter
case class Ingredient(name: String, quantity: Int)
case class Recipe(val ingredients: List[Ingredient])
Wenn ich will, Linsen verwenden, um ein neues Rezept mit der Menge eines einzelnen Bestandteils zu schaffen geändert, was ist der beste Weg, es zu tun?
Der Ansatz, den ich ausprobiert habe, ist eine Linse im laufenden Betrieb zu erstellen: Lens[List[Ingredient], Ingredient]
. Das fühlt sich ein wenig klobig aber:
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
)
}
Sie 'val' bei Klassenparameter weglassen können, sind sie standardmäßig vals – 4lex1v