如何在Kotlin中从mutableList中删除项目

1cosmwyk  于 2023-01-26  发布在  Kotlin
关注(0)|答案(1)|浏览(290)

我正在扫描一个列表,并在mutableList中添加一个唯一的项。通过ScanCallback扫描一个项,但下面的示例是使用Kotlin Flow以便更好地理解并制作一个简单的用例。我给出了一个发出不同类型项的示例。
基本上我想从特定条件中删除项目:-
1.当流数据结束时发出新值。
1.当发送一个项目时,如果我们在30秒内不再接收项目,那么我们从列表中删除该项目。

import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking

class ItemList {
    val scanResultList = mutableListOf<ScanResults>()
    fun doSomething(): Flow<ScanResults> = flow {
       (0..20).forEach {
           delay(200L)
           when (it) {
             in 10..12 -> {
                 emit(ScanResults(Device("item is Adding in range of 10 -- 20")))
             }

             in 15..18 -> {
                 emit(ScanResults(Device("item is Adding in range of 15 -- 18")))
             }

             else -> {
                 emit(ScanResults(Device("item is Adding without range")))
             }
         }
     }
 }

 fun main() = runBlocking {
     doSomething().collectLatest { value ->
         handleScanResult(value)
     }
 }

 private fun handleScanResult(result: ScanResults) {
     if (!scanResultList.contains(result)) {
         result.device?.name?.let {
             if (hasNoDuplicateScanResult(scanResultList, result)) {
                 scanResultList.add(result)
                 println("Item added")
             }
         }
     }
 }

 private fun hasNoDuplicateScanResult(value: List<ScanResults>, result: ScanResults): Boolean {
     return value.count { it.device == result.device } < 1
 }

 data class ScanResults(val device: Device? = null)
 data class Device(val name: String? = null)
}

我没有添加Set,因为在SnapshotStateList中jetpack compose中不可用。

2izufjch

2izufjch1#

我试着用简单的术语来重新描述这个问题,我会说输入是一个虚构的数据类DeviceInfo的流,这样更容易描述。

**问题:**存在DeviceInfo s的源流。我们希望输出为Set<DeviceInfo>的流,其中Set是过去30秒内从源发出的所有DeviceInfo。

(If您可以将此输出Flow转换为State,或者收集它并使用它更新mutablestateListOf,等等。)
这是我想到的一个策略。免责声明:我还没测试过。
使用唯一ID标记每个传入的DeviceInfo(可以基于系统时间或UUID)。使用其最新ID将每个DeviceInfo添加到Map。启动延迟30秒的子协同程序,然后如果ID匹配,则从Map中删除该项目。如果新值已到达,则ID将不匹配,因此过时的子协同程序将静默过期。

val sourceFlow: Flow<DeviceInfo> = TODO()

val outputFlow: Flow<Set<DeviceInfo>> = flow {
    coroutineScope {
        val tagsByDeviceInfo = mutableMapOf<DeviceInfo, Long>()

        suspend fun emitLatest() = emit(tagsByDeviceInfo.keys.toSet())

        sourceFlow.collect { deviceInfo ->
            val id = System.currentTimeMillis()
            if (tagsByDeviceInfo.put(deviceInfo, id) == null) {
                emitLatest() // emit if the key was new to the map
            }
            launch {
                delay(30.seconds)
                if (tagsByDeviceInfo[deviceInfo] == id) {
                    tagsByDeviceInfo.remove(deviceInfo)
                    emitLatest()
                }
            }
        }
    }
}

相关问题