Building on this this post, I needed a clean way to extract nodes in a for comprehension only if they had specific attribute values. Here’s what I came up with:
def attributeValue(attrs: (String, String)*)(n: Node) =
attrs.map { p =>
n.attribute(p._1).exists(_ == p._2)
} reduceLeft(_ && _)
And here’s an example that uses it to extract item objects from an atom feed.
def parseAtomItems(ns: NodeSeq) = ns \\ "entry" flatMap { i =>
for(
t <- i \ "title";
l <- i.\("link").filter(attributeValue(
"type" -> "text/html",
"rel" -> "alternate"
).flatMap(_.attribute("href"))
) yield FeedItem(t text, l text)
}
My question then: is there a cleaner / more idiomatic way to implement attributeValue?
I think the code is pretty good, actually. I’d do this:
Alternatively,
The main advantage to
foralloverreduceLeftbeing that the former will stop at the first false result, while the latter will iterate over every key/value pair, even if a false match is guaranteed.