Scala:通过整数列表定义地图

时间:2014-01-01 14:43:21

标签: r scala functional-programming

来自R的Scala(完全新手)。

说我有两个清单:

val index  = List(0,0,1,0,1)
val a      = List(1,2,3,4,5)

然后index可以定义从ab: List[List[Int]]的自然地图:

1 -> b(0)
2 -> b(0)
3 -> b(1)
4 -> b(0)
5 -> b(1)

那样:

b = List(List(1,2,4), List(3,5))

通常,在给定indexa的情况下,在Scala中创建b的最自然方式是什么?

e.g。在R中,我可以写一下:

run_map <- function(index, a) {
  map <- function(data, i) {
    data[[i]] <- a[which(index == i)]
    data
  }
  Reduce(map, unique(index), list())
}

为任何帮助干杯!

2 个答案:

答案 0 :(得分:4)

如果您希望一个列表包含索引而另一个列表包含值,那么您可以zip将它们放在一起:

val myMap = (a zip b).toMap

其中a包含索引,b包含值。

但是,如果存在重复索引,则您需要执行以下操作:

for{
  (i, list) <- (a zip b) groupBy (_._1)
} yield (i, list map (_._2))

其中您正在压缩,按索引分组,然后映射列表中的值。创建的列表包含索引和值作为元组。

答案 1 :(得分:4)

0)鉴于:

val index  = List(0,0,1,0,1)
val a      = List(1,2,3,4,5)

这是达到解决方案的“迭代”方式:

1)“Zip”2一起列出以产生对列表:

index.zip(a)

结果:

List[(Int, Int)] = List((0,1), (0,2), (1,3), (0,4), (1,5))

2)按列表中该对的第一个元素分组。

index.zip(a).groupBy(_._1)

结果:

Map[Int,List[(Int, Int)]] = Map(1 -> List((1,3), (1,5)), 0 -> List((0,1), (0,2), (0,4)))

3)通过仅列出列表v中每对的第二个元素来删除冗余索引:

index.zip(a).groupBy(_._1).map{ case (i, v) => (i, v.map(_._2)) }

结果:

Map[Int,List[Int]] = Map(1 -> List(3, 5), 0 -> List(1, 2, 4))