将Scala映射转换为列表

时间:2011-08-09 15:26:06

标签: scala data-structures

我有一张地图,我需要映射到另一种类型,结果需要是一个List。我有两种方式(看似)可以实现我想要的,因为在地图上调用地图似乎总是会产生地图。假设我有一些看起来像的地图:

val input = Map[String, List[Int]]("rk1" -> List(1,2,3), "rk2" -> List(4,5,6))

我可以这样做:

val output = input.map{ case(k,v) => (k.getBytes, v) } toList

或者:

val output = input.foldRight(List[Pair[Array[Byte], List[Int]]]()){ (el, res) =>
  (el._1.getBytes, el._2) :: res
}

在第一个例子中,我转换了类型,然后调用toList。我假设运行时类似O(n*2),所需空间为n*2。在第二个示例中,我转换类型并一次生成列表。我假设运行时为O(n),所需空间为n

我的问题是,这些基本相同还是第二次转换会减少内存/时间等?此外,在哪里可以找到有关各种scala转换的存储和运行时成本的信息?

提前致谢。

2 个答案:

答案 0 :(得分:27)

我最喜欢做这种事情的方式是这样的:

input.map { case (k,v) => (k.getBytes, v) }(collection.breakOut): List[(Array[Byte], List[Int])]

使用此语法,您将向map传递重构结果集合所需的构建器。 (实际上,不是构建器,而是构建器工厂。如果您感兴趣,请阅读有关Scala的CanBuildFrom的更多信息。)当您想要从一种集合类型更改为另一种集合类型时,可以完全使用collection.breakOut一个mapflatMap等 - 唯一不好的部分是你必须使用完整类型的注释才能生效(这里,我在表达式之后使用了类型归属)。然后,没有构建中间集合,并且映射时构建了列表。

答案 1 :(得分:23)

第一个示例中的视图映射可以减少大型地图的空间需求:

val output = input.view.map{ case(k,v) => (k.getBytes, v) } toList