Idiomatic Scala for Nested Options

scala

Solution

How about this?

val idOption = children
   .find(_.getName == "Group")
   .flatMap(_.getAttributes.asScala.find(_.getName == "ID"))

Or, with a for comprehension:

val idOption =
  for {
    child <- children.find(_.getName == "Group")
    id <- child.getAttributes.asScala.find(_.getName == "ID")
  } yield id

Problem

Lets say I have an Element object (from JDom actually). It might have a child element called "Group", or it might not. If it does, then it might have an attribute called "ID", or again it might not. I want the ID value if it exists. If Java I would write. ``` private String getId(Element e) { for (Element child : e.getChildren()) if (child.getName().equals("Group")) for (Attribute a : child.getAttributes()) if (a.getName().equals("ID")) return a.getValue(); return null; } ``` In scala I have either ``` val id = children.find(_.getName == "Group") match { case None => None case Some(child) => { child.getAttributes.asScala.find(_.getName == "ID") match { case None => None case Some(a) => Some(a.getValue) } } } ``` Or ``` val id = children.find(_.getName == "Group"). map(_.getAttributes.asScala.find(_.getName == "ID"). map(_.getValue).getOrElse("")).getOrElse("") ``` Which of theirs, or a third, is more idiomatic

Original source