在 Scala 中连接两个长度不等的列表
Join two lists with unequal length in Scala
我有 2 个列表:
val list_1 = List((1, 11), (2, 12), (3, 13), (4, 14))
val list_2 = List((1, 111), (2, 122), (3, 133), (4, 144), (1, 123), (2, 234))
我想将第二个列表中的键替换为第一个列表的值,从而生成如下所示的新列表:
List ((11, 111), (12, 122), (13, 133), (14, 144), (11, 123), (12, 234))
这是我的尝试:
object UniqueTest {
def main(args: Array[String]){
val l_1 = List((1, 11), (2, 12), (3, 13), (4, 14))
val l_2 = List((1, 111), (2,122), (3, 133), (4, 144), (1, 123), (2, 234))
val l_3 = l_2.map(x => (f(x._1, l_1), x._2))
print(l_3)
}
def f(i: Int, list: List[(Int, Int)]): Int = {
for(pair <- list){
if(i == pair._1){
return pair._2
}
}
return 0
}
}
这导致:
((11, 111), (12, 122), (13, 133), (14, 144), (11, 123), (12, 234))
上面的程序是个好方法吗? Scala 中是否有内置函数来处理这种需求,或者有其他方法来进行这种操作?
你可以这样做:
val map = l_1.toMap // transform l_1 to a Map[Int, Int]
// for each (a, b) in l_2, retrieve the new value v of a and return (v, b)
val res = l_2.map { case (a, b) => (map.getOrElse(a, 0), b) }
最惯用的方法是将它们压缩在一起,然后根据需要进行转换:
(list_1 zip list_2) map { case ((k1, v1), (k2, v2)) => (v1, v2) }
你唯一真正过于复杂的是这一行:
val l_3 = l_2.map(x => (f(x._1, l_1), x._2))
您的 f
函数使用命令式样式循环遍历列表以查找键。任何时候您发现自己这样做,都很好地表明您想要的是 map
。通过在每次计算复杂性爆炸时执行 for
循环:映射将允许您获取 O(1)
中给定键的相应值。使用映射,您首先将列表(键值对)转换为明确支持键值对关系的数据结构。
因此,您应该做的第一件事就是构建您的地图。 Scala 提供了一种非常简单的方法来做到这一点 toMap
:
val map_1 = list_1.toMap
那么就是'mapping':
val result = list_2.map { case (key, value) => map_1.getOrElse(key, 0), value) }
这会获取您 list_2
中的每个案例,将第一个值 (key
) 与您 map_1
中的一个键相匹配,检索该值(或默认值 0
) 并将其作为键值元组中的第一个值。
我有 2 个列表:
val list_1 = List((1, 11), (2, 12), (3, 13), (4, 14))
val list_2 = List((1, 111), (2, 122), (3, 133), (4, 144), (1, 123), (2, 234))
我想将第二个列表中的键替换为第一个列表的值,从而生成如下所示的新列表:
List ((11, 111), (12, 122), (13, 133), (14, 144), (11, 123), (12, 234))
这是我的尝试:
object UniqueTest {
def main(args: Array[String]){
val l_1 = List((1, 11), (2, 12), (3, 13), (4, 14))
val l_2 = List((1, 111), (2,122), (3, 133), (4, 144), (1, 123), (2, 234))
val l_3 = l_2.map(x => (f(x._1, l_1), x._2))
print(l_3)
}
def f(i: Int, list: List[(Int, Int)]): Int = {
for(pair <- list){
if(i == pair._1){
return pair._2
}
}
return 0
}
}
这导致:
((11, 111), (12, 122), (13, 133), (14, 144), (11, 123), (12, 234))
上面的程序是个好方法吗? Scala 中是否有内置函数来处理这种需求,或者有其他方法来进行这种操作?
你可以这样做:
val map = l_1.toMap // transform l_1 to a Map[Int, Int]
// for each (a, b) in l_2, retrieve the new value v of a and return (v, b)
val res = l_2.map { case (a, b) => (map.getOrElse(a, 0), b) }
最惯用的方法是将它们压缩在一起,然后根据需要进行转换:
(list_1 zip list_2) map { case ((k1, v1), (k2, v2)) => (v1, v2) }
你唯一真正过于复杂的是这一行:
val l_3 = l_2.map(x => (f(x._1, l_1), x._2))
您的 f
函数使用命令式样式循环遍历列表以查找键。任何时候您发现自己这样做,都很好地表明您想要的是 map
。通过在每次计算复杂性爆炸时执行 for
循环:映射将允许您获取 O(1)
中给定键的相应值。使用映射,您首先将列表(键值对)转换为明确支持键值对关系的数据结构。
因此,您应该做的第一件事就是构建您的地图。 Scala 提供了一种非常简单的方法来做到这一点 toMap
:
val map_1 = list_1.toMap
那么就是'mapping':
val result = list_2.map { case (key, value) => map_1.getOrElse(key, 0), value) }
这会获取您 list_2
中的每个案例,将第一个值 (key
) 与您 map_1
中的一个键相匹配,检索该值(或默认值 0
) 并将其作为键值元组中的第一个值。