score:15
As Peter Neyens points out, Shapeless's SYB works really nicely here, but it will modify all Street
values in the tree, which may not always be what you want. If you need more control over the path, Monocle can help:
import monocle.Traversal
import monocle.function.all._, monocle.macros._, monocle.std.list._
val employeeStreetNameLens: Traversal[Employee, String] =
GenLens[Employee](_.company).composeTraversal(
GenLens[Company](_.addresses)
.composeTraversal(each)
.composeLens(GenLens[Address](_.street))
.composeLens(GenLens[Street](_.name))
)
val capitalizer = employeeStreeNameLens.modify {
case s if s.startsWith("b") => s.capitalize
case s => s
}
As Julien Truffaut points out in an edit, you can make this even more concise (but less general) by creating a lens all the way to the first character of the street name:
import monocle.std.string._
val employeeStreetNameFirstLens: Traversal[Employee, Char] =
GenLens[Employee](_.company.addresses)
.composeTraversal(each)
.composeLens(GenLens[Address](_.street.name))
.composeOptional(headOption)
val capitalizer = employeeStreetNameFirstLens.modify {
case 'b' => 'B'
case s => s
}
There are symbolic operators that would make the definitions above a little more concise, but I prefer the non-symbolic versions.
And then (with the result reformatted for clarity):
scala> capitalizer(employee)
res3: Employee = Employee(
Company(
List(
Address(Street(aaa street)),
Address(Street(Bbb street)),
Address(Street(Bpp street))
)
)
)
Note that as in the Shapeless answer, you'll need to change your Employee
definition to use List
instead of Seq
, or if you don't want to change your model, you could build that transformation into the Lens
with an Iso[Seq[A], List[A]]
.
score:2
Take a look at quicklens
You could do it like this
import com.softwaremill.quicklens._
case class Street(name: String)
case class Address(street: Street)
case class Company(address: Seq[Address])
case class Employee(company: Company)
object Foo {
def foo(e: Employee) = {
modify(e)(_.company.address.each.street.name).using {
case name if name.startsWith("b") => name.capitalize
case name => name
}
}
}
score:8
If you are open to replacing the addresses
in Company
from Seq
to List
, you can use "Scrap Your Boilerplate" from shapeless (example).
import shapeless._, poly._
case class Street(name: String)
case class Address(street: Street)
case class Company(addresses: List[Address])
case class Employee(company: Company)
val employee = Employee(Company(List(
Address(Street("aaa street")),
Address(Street("bbb street")),
Address(Street("bpp street")))))
You can create a polymorphic function which capitalizes the name of a Street
if the name starts with a "b".
object capitalizeStreet extends ->(
(s: Street) => {
val name = if (s.name.startsWith("b")) s.name.capitalize else s.name
Street(name)
}
)
Which you can use as :
val afterCapitalize = everywhere(capitalizeStreet)(employee)
// Employee(Company(List(
// Address(Street(aaa street)),
// Address(Street(Bbb street)),
// Address(Street(Bpp street)))))
Source: stackoverflow.com
Related Query
- How to modify this nested case classes with "Seq" fields?
- How do I make a Java friendly API for case classes with optional fields
- How to convert between to case classes with `mostly the same` fields using Scala Shapeless
- How do I compose nested case classes populated with async mongodb queries in play framework
- Case Classes with optional fields in Scala
- how to serialize case classes with traits with jsonspray
- Merge two case classes in Scala, but with deeply nested types, without lens boilerplate
- How to shapeless case classes with attributes and typeclasses?
- How to find and modify field in nested case classes?
- How to modify a Spark Dataframe with a complex nested structure?
- How do I pull apart Case Classes filled with Options in Scala
- How to define case classes with members with unbound type parameters?
- Recursive transformation between nested case classes where the fields in the target are unaligned subsets of the source class
- How can I get random data generated for scala case classes with the ability to "change some values" for unit testing?
- How to use nested case classes and spray json implicits
- Unzip a sequence of case classes with two fields
- Parsing more than 22 fields with Spray Json without nesting case classes
- How to sort case classes with Option[String] in alphabetical order ignoring None's?
- How to send Json from client with missing fields for its corresponding Case Class after using Json.format function
- How to convert parquet data to case classes with spark?
- Case classes - Copy multiple fields with transforms
- How to make the scala compiler find case classes used with wrong arguments
- Scala: generic function with nested case classes
- How to get Scala case class fields and values as (String, String) with Shapeless or Macro
- How can I use case classes with slicks TSQL interpolator?
- Automatic type class derivation for case classes with Scala Enumeration fields
- How can I avoid boilerplate when generating case classes with ScalaCheck?
- How to convert a JsArray to sequence of case classes with spray-json?
- How to serialize generic case classes with µPickle?
- How to serialize more than 22 fields with nested object in spray?
More Query from same tag
- Apache Toree and Spark Scala Not Working in Jupyter
- Can twitter eval library be used to invoke evaluated code?
- Scala forward or delegate methods to encapsulated object
- Convert Future result into json
- Setting up scala-logging in a sbt module application
- Scala - unbound wildcard exception (Play Framework 2.3 Template)
- testing if a given instance is a (sub)class of a given Class in scala
- How to create an ArrayData or InternalRow given a StructType as Schema in SparkSQL?
- What's the difference between :: and +:
- Typesafe Play WS as dependency in SBT project
- Why does Scala need to add Scala version to libraries?
- Add header to RDD[string] spark scala
- subsets manipulation on vectors in spark scala
- Multiple OR operation in parallel in Scala/Spark
- Reified generics in Scala 2.10
- op-rabbit connection disconnect
- WordCount on Azure using hadoop and spark
- Play file upload : warn: Sending an 2xx 'early' response before end of request was received
- What is a reliable way to find a Scala type's companion object via Java reflection?
- Two Configuration files in Scala-Spray framework
- Generate a custom pattern number sequence in one go
- Call Super Constructor
- Pattern match over List with subclass entries
- How does Scala's (2.8) Manifest work?
- Scala's naming convention for traits
- Two seemingly identical semantics: one binds implicitly, the other does not
- Does not conform the expected type
- How can I compile only the Spark Core and Spark Streaming (so that I can get unit test utilities of Streaming)?
- What is the cost of access to a configuration property?
- scala implicit conversion for case object