Jas*_*Jas 9 scala rx-scala couchbase-java-api
我有一个代码调用couchbase获取一些行如下:
val gotValues: Observable[JsonDocument] = Observable.from(rowKeys).flatMap(id =>
couchbaseBucket.async().get(id))
Run Code Online (Sandbox Code Playgroud)
如果我有1,2,3,4,5,6作为输入行键,并且DB中只存在1,2,3行,那么observable只会收到1,2,3的通知.
然而,我的要求是我返回一个1,2,3 true(存在于db中)和4,5,6 with false(在DB中不存在)的映射.我设法用scala observable做到了,但是我使用中间地图数据结构来返回包含所有id的总地图.下面是一个模拟我的问题的示例代码..
object Main extends App {
import rx.lang.scala.Observable
val idsToFetch = Seq(1,2,3,4,5,6)
println(isInDBOrNot()) // {1=true, 2=true, 3=true, 4=false, 5=false, 6=false}
private def isInDBOrNot(): ConcurrentHashMap[Int, Boolean] = {
val inAndNotInDB = new java.util.concurrent.ConcurrentHashMap[Int, Boolean]
// - How can I avoid the additional data structure?
// - In this case a map, so that the function will return
// a map with all numbers and for each if exist in DB?
// - I mean I want the function to return a map I don't
// want to populate that map inside the observer,
// it's like a mini side effect I would rather simply
// manipulate the stream.
Observable.from(idsToFetch)
.filterNot(x => x == 4 || x == 5 || x == 6) // Simulate fetch from DB, 4,5,6 do not exist in DB, so not returned.
.subscribe(
x => inAndNotInDB.put(x, true),
e => println(e),
() => idsToFetch.filterNot(inAndNotInDB.containsKey)
.foreach(inAndNotInDB.put(_, false)) // mark all non-found as false.
)
inAndNotInDB
}
}
Run Code Online (Sandbox Code Playgroud)
无论如何没有中间映射(没有填充中间数据结构,但只能通过操纵流)?看起来不干净!! .谢谢.
您的问题似乎是因为您使用了flatMap
这样的事实,如果DB中没有给定给定的数据id
并且您得到一个空的Observable
,那么flatMap
就不会产生任何输出id
.所以看起来你需要的是defaultIfEmpty,它被翻译成Scala的orElse
.您可以使用orElse
内部返回一些默认值flatMap
.所以要修改你的例子:
def fetchFromDb(id: Int): Observable[String] = {
if (id <= 3)
Observable.just(s"Document #$id")
else
Observable.empty
}
def gotValue(idsToFetch: Seq[Int]): Observable[(Int, Boolean)] = {
Observable.from(idsToFetch).flatMap((id: Int) => fetchFromDb(id).map(_ => (id, true)).orElse((id, false)))
}
println(gotValue(Seq(1, 2, 3, 4, 5, 6)).toBlocking.toList)
Run Code Online (Sandbox Code Playgroud)
打印
List((1,true),(2,true),(3,true),(4,false),(5,false),(6,false))
或者你可以Option
用来返回Some(JsonDocument)
或者None
如
def gotValueEx(idsToFetch: Seq[Int]): Observable[(Int, Option[String])] = {
Observable.from(idsToFetch).flatMap((id: Int) => fetchFromDb(id).map(doc => (id, Option(doc))).orElse((id, None)))
}
println(gotValueEx(Seq(1, 2, 3, 4, 5, 6)).toBlocking.toList)
Run Code Online (Sandbox Code Playgroud)
打印
列表((1,Some(Document#1)),(2,Some(Document#2)),(3,Some(Document#3)),(4,None),(5,None),(6,没有))
归档时间: |
|
查看次数: |
212 次 |
最近记录: |