Reputation: 2845
I have some issue with this this simple for yield operation.
for {
relatedPostMd <- postMd.get.filter(_.fromID == userID)
nextUrl <- (ch \ "paging" \ "next").asOpt[String] // string
} yield (nextUrl, relatedPostMd)
If the result of the filter is none (no match for the filter opration).
Then all the Tuple is empty even though im sure that there is value in nextUrl .
the complete method
def getPostMD(userID: String, url: String): Future[List[(String, PostMD)]] = {
val chunk: Future[JsValue] = Methods.getJsonValue(url)
chunk.map(ch => {
val postMd: Option[List[PostMD]] = (ch \ "data").asOpt[List[PostMD]]
for {
relatedPostMd <- postMd.get.filter(_.fromID == userID)
nextUrl <- (ch \ "paging" \ "next").asOpt[String]
} yield (nextUrl, relatedPostMd)
})
}
thanks,
miki
Upvotes: 0
Views: 710
Reputation: 1512
May be you need something like this:
val postMd: Option[List[Int]] = ???
val next: Option[String] = ???
val defaultPostMd = -1
val defaultNext = ""
val nextVals = next.toList
val res = postMd
.getOrElse(Nil)
.filter(_ % 2 == 1) // << your filter
.zipAll(nextVals, defaultPostMd, nextVals.lift(0).getOrElse(defaultNext))
1)
val postMd: Option[List[Int]] = Some(List(1, 2, 3, 4, 5))
val next: Option[String] = Some("next")
List((1,next), (3,next), (5,next))
2)
val postMd: Option[List[Int]] = None
val next: Option[String] = Some("next")
List((-1,next))
3)
val postMd: Option[List[Int]] = Some(List(1, 2, 3, 4, 5))
val next: Option[String] = None
List((1,), (3,), (5,))
4)
val postMd: Option[List[Int]] = None
val next: Option[String] = None
List()
Upvotes: 0
Reputation: 40510
for
comprehension is sugar for flatMap
. So, your code is basically equivalent to this:
postMd.get.filter(_.fromID == userID).map { relatedPostMd =>
x
}
Obviously, when list, returned by filter
is empty, the .map
produces an empty list as a result. If you want some special handling for that case, you first of all need to decide what you want the second element of the tuple to be (and how many tuples you want to return) when there are no matches. Then you could do something like this:
postMd.get.filter(_.fromID == userID) match {
case Nil => List(whateverYourSentinelValueIs)
case x => x
}.map { relatedPostMd =>
((ch \ "paging" \ "next"), relatedPostMd)
}
Upvotes: 1