按类别过滤对象的可流动列表并分组到另一个流中的对象列表

filter flowable list of object by category and group into another list of object in flow

是否可以按类别过滤和分组 Flow<List<Object A>>

我发现问题非常相似 ,但运气不好 :(

在这里我分享我尝试过的方法,

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
            }
        }
    }

  ...

我不知道这种方法是否正确,请让我知道如何使用流程解决这个问题

流在被收集之前不会发出任何值。所以你需要收集你的流量:

private fun filterCarByCategory(){
    viewModelScope.launch {
        getAllCarsAsFlow().collect { carList ->
            // Rest everything same
        }
    }
}

编辑: 如果 _mutableStateFlowCarList 的唯一目的是向 UI 提供数据,则无需在此处使用 StateFlow,一个普通的 Flow 就可以完成这项工作。

val filteredCarList = getAllCarsAsFlow().map { carList ->
    categoryList.map { (id, name) ->
        CarsByCategory (
            categoryId = id,
            categoryName = name,
            carList = carList.filter { car -> car.category == id }
        )
    }
}