JohnBigs
JohnBigs

Reputation: 2811

flatting out few hierarchal Options in scala

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

Answers (2)

Evgeny Lyutikov
Evgeny Lyutikov

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

amorfis
amorfis

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

Related Questions