如何基于kotlin / java中的另一个列表过滤列表?

时间:2018-08-10 08:45:12

标签: list filter kotlin

我有两种类型FooApiFooModel

class FooApi (var aId) 
class FooModel(var mId)

是简化下面基于FooModel列表过滤FooApi列表的功能的一种方法:

fun f(fooModelList: List<FooModel>, fooApiList: List<FooApi>) : List<FooModel> {
  return fooModelList.filter { fooApiList.map { it.aId }.contains ( it.mId ) }
}

2 个答案:

答案 0 :(得分:3)

我觉得还好。我只会更改一些次要的东西(虽然不是必需的),以便最终得到如下内容:

 fun List<FooModel>.f(fooApiList: List<FooApi>) = filter { m -> fooApiList.any { it.aId == m.mId } }

我这样做的某些原因:

  • 我认为过滤总是应用于FooModel列表中,对吗? (这是扩展功能将类型缩小为List<FooModel>的原因)
  • 您对fooApiList的映射对象不感兴趣,所以这就是为什么我使用any的原因;好处还在于,现在比较的两个值都彼此相邻
  • 概述所有内容非常容易,甚至可以省略方法主体(并因此省略返回类型,return语句等)

仍然,这几乎与您已经做的一样……减少了一些代码并重新安排了……顺便说一下:

val listA : List<FooModel> = TODO()
val listB : List<FooApi> = TODO()

val containedList = listA.f(listB)

如果您更经常需要这种构造,那么以下更通用的解决方案可能会有所帮助:

fun <T, U> List<T>.intersect(uList: List<U>, filterPredicate : (T, U) -> Boolean) = filter { m -> uList.any { filterPredicate(m, it)} }

然后您还可以像这样使用

val containedList = listA.intersect(listB) {
    a, b -> a.aId == b.mId
}

然后您的f可能甚至看起来像:

fun List<FooModel>.f(fooApiList: List<FooApi>) = intersect(fooApiList) { a, b ->  a.mId == b.aId }

答案 1 :(得分:1)

我会做类似的事情

val apiList = listOf(FooApi(1), FooApi(2), FooApi(3))
val modelList = listOf(FooModel(1), FooModel(3))

val output = apiList.flatMap { api -> modelList.filter { api.id == it.id }}

Givin作为输出

  

[FooModel(id = 1),FooModel(id = 3)]

我不知道两者之间的差异是否很大...