在Scala中,在给定长度为N的列表的情况下创建长度为N的嵌套HashMap

时间:2016-05-04 05:05:05

标签: java scala

如何在给定值列表的情况下创建嵌套的hashmap?

List(1,2,3,4).toMap => Map(1 -> Map(2 -> Map(3 -> 4)))

之后,如何将其与其他地图合并?

List(1,2,3,4).toMap => Map(1 -> Map(2 -> Map(3 -> 4)))
List(1,2,3,5).toMap => Map(1 -> Map(2 -> Map(3 -> 5)))
Map(1 -> Map(2 -> Map(3 -> List(4,5)))

我基本上想要执行

List(List(1,2,3,8), List(2,3,7,9)).groupBy(x => x(0)).
groupBy(x => x(1)).
groupBy(x=>x(2)) 
... 
...
.groupBy(x=>x(n))

其中N是内部列表中值的长度。

2 个答案:

答案 0 :(得分:2)

我们可以毫不费力地实现接近您的第一个要求的东西。

scala> List(1,2,3,4).foldRight(Map[Int,Map[Int,_]]()){case (a,b) => Map(a->b)}
res0: scala.collection.immutable.Map[Int,scala.collection.immutable.Map[Int, _]] 
     = Map(1 -> Map(2 -> Map(3 -> Map(4 -> Map()))))

但我认为没有足够的信息可以完全理解你的第二个请求。例如:如何合并以下列表?

List(1,2,3,8)
List(2,3,7,9)

<强>更新

从您的评论中听起来似乎最好的方法可能是在嵌套之前合并列表。这可以通过多种不同的方式完成,具体取决于您的要求。

例如:如果订单很重要(看起来很像),列表是否可以轻松排序?如果你使用Int那么那就是琐碎的。

def nest[A](input: List[A]): Map[A, Map[A,_]] =
  input.foldRight(Map[A,Map[A,_]]()){case (a,b) => Map(a->b)}

val lst1 = List(1,2,3,8)
val lst2 = List(2,3,7,9)
val result = nest( (lst1 ++ lst2).distinct.sorted )
//result: Map(1 -> Map(2 -> Map(3 -> Map(7 -> Map(8 -> Map(9 -> Map()))))))

但我怀疑这些简单明了的例子可能会偏离现实世界的用例。

答案 1 :(得分:0)

我们可以通过识别foldRight中的初始值是列表的最后两个元素来稍微改善结果。也就是说,34变为Map(3 -> 4 ),可以通过执行一些丑陋的索引来将其用作折叠中的初始值。

scala> val xs = List(1,2,3,4)
xs: List[Int] = List(1, 2, 3, 4)

scala> xs.dropRight(2).foldRight(Map[Int, Any](xs(xs.length - 2) -> xs(xs.length - 1)))((a,b) => Map(a -> b))
res1: ... = Map(1 -> Map(2 -> Map(3 -> 4)))

也可以使用更长的列表:

scala> xs.dropRight(2).foldRight(Map[Int, Any](xs(xs.length - 2) -> xs(xs.length - 1)))((a,b) => Map(a -> b))
res6: ... = Map(1 -> Map(2 -> Map(3 -> Map(4 -> Map(5 -> Map(6 -> Map(7 -> Map(8 -> 9))))))))