Reputation: 2811
I'm a bit lost with flatting out a case class that has a bunch of Option's.
My case class is Person, who looks like this:
case class Person(name: String, metadata: Option[Metadata])
case class Metadata(contacts: Option[List[Contact]])
case class Contact(id: Int, isAvailable: Option[Boolean])
what I want is to take an Option of Person and make a copy of that person but with contacts that isAvailable equals true.
so if we have the below object:
Some(
Person(
"John",
Some(
Metadata(
Some(
List(
Contact(1, Some(true)),
Contact(2, None),
Contact(3, Some(false)),
Contact(4, Some(true))
)
)
)
)
)
)
the result would be:
Some(
Person(
"John",
Some(
Metadata(
Some(
List(
Contact(1, Some(true)),
Contact(4, Some(true))
)
)
)
)
)
)
how would you do that?
Upvotes: 0
Views: 34
Reputation: 56
Without external dependencies, something like this:
for {
person <- personOption
metadata <- person.metadata
contacts <- metadata.contacts
} yield Person(
person.name,
Some(Metadata(
Some(contacts.filter(_.isAvailable.contains(true)))
))
)
Upvotes: 1
Reputation: 15770
Take a look at quicklens: https://github.com/softwaremill/quicklens
It's going to be:
person.modify(_.metadata.contacts).using(_.filter(_.isAvailable == Some(true))
If you need to modify Option[Person]
, you need to add map
:
personOpt.map(_.modify(_.metadata.contacts).using(_.filter(_.isAvailable == Some(true)))
Upvotes: 1