通过比较每个类型的值,从另外两个不同类型的列表中创建一个新列表
说我有两个对象的列表,这两个对象都实现了一个接口,但在其他方面是不相关的。 我如何创建一个新的对象集合,其中只包含与另一个列表中的值匹配的列表中的一个对象? 很明显,我可以使用for循环手动执行此操作,但是我想知道如何使用Kotlin的标准库收集过滤函数来执行此操作。 我已经阅读了文档,我很确定我需要使用filterTo
,但是我不确定如何设置谓词或变换,而且我还不太了解Kotlin,以便更好地理解文档。
我有点难以弄清楚如何把我想要做的事情变成有意义的段落,所以这里是一个例子:
interface Ids { val id: Int } data class A(override val id: Int, val name: String) : Ids data class B(override val id: Int, val timestamp: Long) : Ids fun main(args: Array<String>) { val a1 = A(1, "Steve") val a2 = A(2, "Ed") val aCol = listOf(a1, a2) val b2 = B(2, 12345) val b3 = B(3, 67890) val bCol = listOf(b2, b3) val matches = mutableListOf<B>() // This is where I'm stuck. // I want to filter bCol using objects from aCol as a filter. // The result should be that matches contains only a single object: b2 // because bCol[0].id == aCol[1].id // I'm guessing I need to start with something like this: bCol.filterTo(matches) { ??? } }
一个简单的方法是搜索aCol
为aCol
中的每个b
使用相同id的对象:
bCol.filter { b -> aCol.any { a -> a.id == b.id } }
但是,如果您的列表足够大,那么这可能会变得太慢。
为了使其更具可扩展性,您可以首先在aCol
构建一组所有ID:
val aColIds = aCol.map { it.id }.toSet()
然后使用Set.contains
方法来确定b.id
是否在aColIds
:
bCol.filter { it.id in aColIds } // or equivalent bCol.filter { aColIds.contains(it.id) }