来自R的Scala(完全新手)。
说我有两个清单:
val index = List(0,0,1,0,1)
val a = List(1,2,3,4,5)
然后index
可以定义从a
到b: 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))
通常,在给定index
和a
的情况下,在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())
}
为任何帮助干杯!
答案 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))