Kotlin 使用元素子列表筛选嵌套列表

Kotlin 使用元素子列表筛选嵌套列表,kotlin,Kotlin,在下面的代码中,我试图过滤子列表值为2、3或4的主对象列表。即使只有一个元素,我也无法过滤列表。你们能帮我指出需要使用什么样的lamba函数来获得expectedList作为输出吗 fun main() { data class ChildObject(var id: Int, var subList: List<Int>) data class MasterObject(var identifier: Int, var listObject: List<Ch

在下面的代码中,我试图过滤子列表值为2、3或4的主对象列表。即使只有一个元素,我也无法过滤列表。你们能帮我指出需要使用什么样的lamba函数来获得expectedList作为输出吗

fun main() {

    data class ChildObject(var id: Int, var subList: List<Int>)
    data class MasterObject(var identifier: Int, var listObject: List<ChildObject>)

val initialList = arrayListOf<MasterObject>(
    MasterObject(100, arrayListOf(ChildObject(101, arrayListOf(10, 2, 13)), ChildObject(102, arrayListOf(14, 15, 6)), ChildObject(103, arrayListOf(17, 20, 9)))),
    MasterObject(200, arrayListOf(ChildObject(201, arrayListOf(11, 40, 6)), ChildObject(202, arrayListOf(4, 5, 20)), ChildObject(203, arrayListOf(7, 13, 9)))),
    MasterObject(300, arrayListOf(ChildObject(301, arrayListOf(1, 2, 30)), ChildObject(302, arrayListOf(4, 15, 60)), ChildObject(303, arrayListOf(7, 20, 90)))))

/*actual goal is to print final list of master objects containing any of (2,3,4) elements in listobject. for now I am stuck with filtering single element */
val expectedList = arrayListOf<MasterObject>(
    MasterObject(100, arrayListOf(ChildObject(101, arrayListOf(10, 2, 13)))),
    MasterObject(200, arrayListOf(ChildObject(202, arrayListOf(4, 5, 20)))),
    MasterObject(300, arrayListOf(ChildObject(301, arrayListOf(1, 2, 30)),ChildObject(302, arrayListOf(4, 15, 60)))))


    /*not able apply 2 filters and resulting in error*/
    val finalListWithFilter = initialList.filter { masterObject ->
        masterObject.listObject.filter { childObject -> childObject.subList.contains(2) }
    }

    /* prints entire childObject list for any or doesnt print any list for all*/
    val finalListWithAny = initialList.filter { masterObject ->
        masterObject.listObject.any { childObject ->
            childObject.subList.contains(2)
        }
    }

    /*prints list childObject but I need list of masterObject*/
    val finalListWithMap = initialList.flatMap { masterObject ->
        masterObject.listObject.filter { childObject ->
            childObject.subList.contains(2)
        }
    }

    println(finalListWithAny)
    print(finalListWithMap)
}
fun main(){
数据类ChildObject(变量id:Int,变量子列表:List)
数据类主对象(变量标识符:Int,变量列表对象:List)
val initialList=arrayListOf(
主对象(100,arrayListOf(ChildObject(101,arrayListOf(10,2,13)),ChildObject(102,arrayListOf(14,15,6)),ChildObject(103,arrayListOf(17,20,9)),
主对象(200,arrayListOf(ChildObject(201,arrayListOf(11,40,6)),ChildObject(202,arrayListOf(4,5,20)),ChildObject(203,arrayListOf(7,13,9)),
主对象(300,arrayListOf(ChildObject(301,arrayListOf(1,2,30)),ChildObject(302,arrayListOf(4,15,60)),ChildObject(303,arrayListOf(7,20,90()))
/*实际的目标是打印包含listobject中任何(2,3,4)元素的主对象的最终列表*/
val expectedList=arrayListOf(
主对象(100,arrayListOf(ChildObject(101,arrayListOf(10,2,13))),
主对象(200,arrayListOf(ChildObject(202,arrayListOf(4,5,20))),
主对象(300,arrayListOf(ChildObject(301,arrayListOf(1,2,30)),ChildObject(302,arrayListOf(4,15,60щщ)))
/*无法应用2个筛选器并导致错误*/
val finalListWithFilter=initialList.filter{masterObject->
masterObject.listObject.filter{childObject->childObject.subList.contains(2)}
}
/*为任何对象打印整个childObject列表,或不为所有对象打印任何列表*/
val finalListWithAny=initialList.filter{masterObject->
masterObject.listObject.any{childObject->
子列表包含(2)
}
}
/*打印列表子对象,但我需要主对象列表*/
val finalListWithMap=initialList.flatMap{masterObject->
masterObject.listObject.filter{childObject->
子列表包含(2)
}
}
println(最终期限)
打印(finalListWithMap)
}
谢谢

这很有效:

/**
 * You can edit, run, and share this code. 
 * play.kotlinlang.org 
 */

fun main() {
    println("Hello, world!!!")
   
    
    val list = listOf(
        mapOf( "id" to 100, "name" to "xyz", "sublist" to listOf(2, 3, 4 )),
        mapOf( "id" to 101, "name" to "abc", "sublist" to listOf(1, 5, 10 )),
        mapOf( "id" to 102, "name" to "qwerty", "sublist" to listOf(2, 6, 12 ))
       )
    
    val result = list.filter { 
        (it["sublist"] as List<Int>).any { it == 2 }
      
    }
    println(result)

    data class ChildObject(var id: Int, var subList: List<Int>)
data class MasterObject(var identifier: Int, var listObject: List<ChildObject>)
val initialList = arrayListOf<MasterObject>(
    MasterObject(100, arrayListOf(ChildObject(101, arrayListOf(1, 2, 3)), ChildObject(102, arrayListOf(4, 5, 6)), ChildObject(103, arrayListOf(7, 2, 9)))),
    MasterObject(200, arrayListOf(ChildObject(201, arrayListOf(1, 4, 6)), ChildObject(202, arrayListOf(4, 5, 2)), ChildObject(203, arrayListOf(7, 3, 9)))),
    MasterObject(300, arrayListOf(ChildObject(301, arrayListOf(1, 2, 3)), ChildObject(302, arrayListOf(4, 5, 6)), ChildObject(303, arrayListOf(7, 2, 9)))))

/*actual goal is to print final list of master objects containing any of (2,3,4) elements in listobject. for now I am stuck with filtering single element */
val expectedList = arrayListOf<MasterObject>(
    MasterObject(100, arrayListOf(ChildObject(101, arrayListOf(1, 2, 3)), ChildObject(103, arrayListOf(7, 2, 9)))),
    MasterObject(200, arrayListOf(ChildObject(202, arrayListOf(4, 5, 2)))),
    MasterObject(300, arrayListOf(ChildObject(301, arrayListOf(1, 4, 3)))))

var resultList = initialList.filter { master ->
    master.listObject.filter { child ->
        child.subList.any { it == 2 } || child.subList.any { it == 3 } || child.subList.any { it == 4 }
    }.size > 0
}

print(resultList)
}

在这种情况下,您对过滤工作原理的假设是错误的。过滤只是帮助您缩小对象列表的范围。但是,无论您过滤什么,内容(对象本身)都将始终保持相同的外观。这也是为什么对id为2、3和4的子元素进行过滤基本上会产生输入列表的原因,因为每个主对象都有这样一个元素

由于您的数据类不包含可变列表,我假设主对象的副本是可以的,因此以下可能是您的工作解决方案:

val childrenMatchingIds = listOf(2, 3, 4) // the child id's you are interested in
val result = initialList.mapNotNull { master -> // [1]
  master.listObject.filter { child -> childrenMatchingIds.any(child.subList::contains) } // [2]
    .takeUnless { it.isEmpty() } // [3]
    ?.let { // [4]
      master.copy(listObject = it) // [5]
    }
}
  • 确保稍后跳过没有子对象匹配的主对象
  • 将返回所有子项与id匹配的子项(因此在筛选器中)。注意:此列表与原始主对象分离。但是,其内容是对主对象的
    listObject
    -列表中相同对象的有效引用
  • 在这里,我们确保如果此列表为空,我们将继续使用
    null
    (请参阅)
  • 如果它是
    null
    ,我们将选择忽略它(请参阅)
  • 最后,我们将旧信息复制(参见)到一个全新的(分离的-即不再相同,但可能包含相同的引用)主对象,该主对象包含旧对象包含的所有详细信息,
    listObject
    中的引用与旧主对象中的引用相同,但经过过滤
  • 回到第1点和第4点:
    mapNotNull
    将过滤掉不包含子对象的主对象,因为我们过滤掉了空的子对象(因此从
    takeIf
    获取
    null

    如果还有什么不清楚的地方,请随时提出澄清问题


    是的:可能还有十几种其他的变体可以实现这一点。只要您需要主对象的过滤表示,您将始终需要一个新的主对象。如果您的列表是可变的,并且您更希望删除元素,那么解决方案将完全不同(有其优点和缺点)。

    您可以执行
    list.filter{it.subList.contains(2)}
    我尝试使用嵌套过滤器。显示更新的对象类型和我的查询更新了我的对象结构。你能根据我的对象结构更新你的答案吗?我做了,检查一下谢谢你的帮助!!。但您的答案是将输入打印为输出。我已更新了输入值以显示差异您询问的是筛选还是映射?过滤是保持对象不变,映射可能会更改对象。我已经完成了筛选,如果您需要映射,请添加正确的问题,因为当前是“筛选嵌套列表,其中包含元素的小列表,而不使用转换”
    
    val childrenMatchingIds = listOf(2, 3, 4) // the child id's you are interested in
    val result = initialList.mapNotNull { master -> // [1]
      master.listObject.filter { child -> childrenMatchingIds.any(child.subList::contains) } // [2]
        .takeUnless { it.isEmpty() } // [3]
        ?.let { // [4]
          master.copy(listObject = it) // [5]
        }
    }