通过另一个 LiveData<Map> <String> android kotlin 过滤 LiveData



我有一个来自房间数据库的LiveData<Map<A, List<B >>,还有一个searchQuery,我想用它来过滤B对象。例如,

data class Server(
val serverId: Int
)
data class Group(
val serverId: Int,
val groupId: Int,
val description: String
)
LiveData<Map<Server, List<Group>>
So I have 
Server(100)
Group(100, 1, "AAAA")
Group(100, 2, "AAAB")
Group(100, 3, "AABB")
Server(200)
Group(200, 1, "AAAA")
Group(200, 2, "AAAB")
Group(200, 3, "AABB")

现在,我有一个searchableString = "BB"所以LiveData我希望它在描述字段上被过滤,结果必须是

Server(100)
Group(100, 3, "AABB")
Server(200)
Group(200, 3, "AABB")

有什么办法在科特林身上做到这一点吗?

首先编写一个扩展函数来过滤地图:

fun Map<Server, List<Group>>.filterGroups(descFilter: String) = mapValues { _, groups ->
groups.filter { descFilter in it.description }
}

如果您想消除空服务器,可以在上述函数的末尾添加一个.filter { _, groups -> groups.isNotEmpty() }

假设你的LiveData在视图模型中,我会为搜索词创建一个私有的MutableLiveData,并使用公共属性对其进行更改。然后使用switchMap根据你的输入生成最终结果。

val sourceMapFromRoom: LiveData<Map<Server, List<Group>> = //...
private val _searchFilter = MutableLiveData<String>("")
val searchFilter: String
get() = _searchFilter.value
set(value) { _searchFilter.value = value }
val filteredMap = _searchFilter.switchMap { searchString ->
sourceMapFromRoom.map { it.filterGroups(searchString) }
}

switchMap是Rx流或Kotlin流中flatMapLatest的LiveData等价物。