按类别过滤可流动的对象列表并将其分组到另一个流动对象列表中
Posted
技术标签:
【中文标题】按类别过滤可流动的对象列表并将其分组到另一个流动对象列表中【英文标题】:filter flowable list of object by category and group into another list of object in flow 【发布时间】:2021-12-23 17:00:43 【问题描述】:是否可以按类别过滤和分组Flow<List<Object A>>
。
我发现问题非常相似 here ,但没有运气:(
我在这里分享我尝试过的方法,
viewModel 中的代码:
class HomeViewModel: ViewModel()
data class Car(val id: Int, val name: String, val category: Int)
data class CarsByCategory(val categoryId:Int, val categoryName: String, val carList: List<Car>)
private val categoryList =
mapOf<Int, String>(1 to "Audi", 2 to "BMW", 3 to "Chevrolet", 4 to "Dodge", 5 to "Others")
private val mutableCarList: MutableList<CarsByCategory> = mutableListOf()
private val _mutableStateFlowCarList: MutableStateFlow<List<CarsByCategory>> = MutableStateFlow(emptyList())
val filteredCarList: StateFlow<List<CarsByCategory>> = _mutableStateFlowCarList
private fun getAllCarsAsFlow(): Flow<List<Car>>
val cars = listOf(
Car(id = 1, name = "A1", category = 1),
Car(id = 1, name = "A2", category = 1),
Car(id = 1, name = "BMW X1", category = 2),
Car(id = 1, name = "BMW X7", category = 2),
Car(id = 1, name = "M Roadster", category = 2),
Car(id = 1, name = "Bolt EUV", category = 3),
Car(id = 1, name = "Blazer", category = 3),
Car(id = 1, name = "Challenger", category = 4),
Car(id = 1, name = "Neon", category = 4),
Car(id = 1, name = "Frontier", category = 5)
)
return flowOf(cars)
private fun filterCarByCategory()
getAllCarsAsFlow().map carList ->
for (key in categoryList.keys)
val filteredList = carList.filter car -> car.category == key
mutableCarList.add(
CarsByCategory(
categoryId = key,
categoryName= categories.getValue(key),
carList = filteredList
)
)
_mutableStateFlowCarList.value = mutableCarList.toList()
init
filterCarByCategory()
片段中的代码:
....
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
lifecycleScope.launchWhenStarted
homeViewModel.filteredCarList.collect
Log.d(TAG, "onViewCreated: $it.size")
// here getting car list size is 0
...
我不知道这是不是正确的方法,请告诉我如何使用流解决这个问题
【问题讨论】:
【参考方案1】:流在被收集之前不会发出任何值。所以你需要收集你的流量:
private fun filterCarByCategory()
viewModelScope.launch
getAllCarsAsFlow().collect carList ->
// Rest everything same
编辑:如果 _mutableStateFlowCarList
的唯一目的是向 UI 提供数据,那么您无需在此处使用 StateFlow
,只需普通的 Flow
即可。 p>
val filteredCarList = getAllCarsAsFlow().map carList ->
categoryList.map (id, name) ->
CarsByCategory (
categoryId = id,
categoryName = name,
carList = carList.filter car -> car.category == id
)
【讨论】:
是的,但是我们可以根据我们的要求将现有数据流流转换为包含过滤列表的另一种类型,然后在 UI 屏幕上而不是在 ViewModel 上收集。我的意思是有什么简单的方法可以使用 flow 来做同样的事情吗? 使用StateFlow
有什么特殊原因吗?为什么不是普通的Flow
?可以使用 map
运算符生成普通的 Flow
,然后您可以在 UI 中收集该运算符。
另外,我上面写的代码仍然使用_mutableStateFlowCarList
,你可以在 UI 中收集它(就像你现在所做的那样)。唯一的变化是将map
替换为collect
。
我不这么认为,我们可以在外部流上发出 mutableCarList 值还是需要为它创建另一个流?
另外,在您的原始代码中,您没有在任何地方清除 mutableCarList
。是故意的吗?以上是关于按类别过滤可流动的对象列表并将其分组到另一个流动对象列表中的主要内容,如果未能解决你的问题,请参考以下文章
Flowable入门系列文章90 - 一般可流动的REST原则 01