Scala中对动态生成的嵌套列表生成元素笛卡尔积的实现
嘿,这个需求在Scala里其实有非常优雅的解决方案,完全不需要提前知道嵌套列表的层数,用标准库的foldLeft就能轻松搞定!
通用实现方案(返回列表形式的笛卡尔积)
因为元组的元素个数是编译时固定的,动态场景下返回List[List[String]]会更灵活(如果一定要元组的话后面会补充进阶方案)。核心思路是用foldLeft逐步累积笛卡尔积:
def cartesianProduct(input: List[List[String]]): List[List[String]] = { // 初始值:包含一个空列表的列表,作为笛卡尔积的构建起点 input.foldLeft(List(List.empty[String])) { (accumulated, currentList) => // 用for推导式把累积的所有组合和当前子列表的元素逐一配对 for { existingCombination <- accumulated item <- currentList } yield existingCombination :+ item } }
测试你的示例
输入1:
val input1 = List(List("1", "2"), List("3", "4")) cartesianProduct(input1) // 输出:List(List("1", "3"), List("1", "4"), List("2", "3"), List("2", "4"))
输入2:
val input2 = List(List("1", "2"), List("3", "4"), List("6", "7"), List("8")) cartesianProduct(input2) // 输出:List(List("1","3","6","8"), List("1","3","7","8"), List("1","4","6","8"), List("1","4","7","8"), List("2","3","6","8"), List("2","3","7","8"), List("2","4","6","8"), List("2","4","7","8"))
为什么这个方案适用于动态场景?
foldLeft会遍历输入的每个子列表,从空列表开始,每一步都把之前生成的所有组合和当前子列表的元素进行配对,逐步构建出完整的笛卡尔积。不管你的嵌套列表是2层、4层还是动态生成的N层,这个方法都能正确处理。
进阶:如果一定要返回元组?
Scala的元组类型是固定长度的(比如(String, String)和(String, String, String)是完全不同的类型),动态场景下直接返回元组需要借助Shapeless这样的库来处理异构列表(HList)。如果你的业务场景确实需要元组输出,可以参考Shapeless的Cartesian类型类,但大多数情况下,返回List[List[String]]已经足够满足动态生成列表的需求了。
内容的提问来源于stack exchange,提问作者user2895589
相关产品推荐
相关产品推荐

