通过比较每种类型的值,从另外两个不同类型的列表中创建一个新列表

Jor*_*ndo 3 filtering list kotlin

我有两个对象列表,它们都实现了一个接口,但在其他方面是不相关的.如何创建一个新的对象集合,其中只包含与其他列表中的值匹配的其中一个列表的对象?

显然我可以使用for循环并手动执行此操作,但我想知道如何使用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) { ??? }
}
Run Code Online (Sandbox Code Playgroud)

Ily*_*lya 5

一种直接的方法是将搜索aCol与用于每个相同的id的对象bbCol:

bCol.filter { b -> aCol.any { a -> a.id == b.id } }
Run Code Online (Sandbox Code Playgroud)

但是,如果您的列表足够大,那可能会变得太慢.

为了使其更具可伸缩性,您可以先在以下位置构建一组所有ID aCol:

val aColIds = aCol.map { it.id }.toSet()
Run Code Online (Sandbox Code Playgroud)

然后使用Set.contains方法确定是否b.idaColIds:

bCol.filter { it.id in aColIds }
// or equivalent
bCol.filter { aColIds.contains(it.id) }
Run Code Online (Sandbox Code Playgroud)