Scala - 通过公共(public)元素合并两个元组列表

标签 scala list group-by scala-collections

如何合并两个模拟 Chasles 关系的元组列表?

(a, b), (b, c) => (a, c)

这是一个例子:

val l1 = List(("Dan", "b"), ("Dan","a"), ("Bart", "c"))
val l2 = List(("a", "1"), ("c", "1"), ("b", "3"), ("a", "2"))

预期结果是:

val result = List(("Dan", "3"), ("Dan", "1"), ("Dan", "2"), ("Bart", "1"))

最佳答案

您基本上要考虑第一个列表中的一个元素和第二个列表中的所有元素对,并保留“b”元素匹配的那些。

换句话说,我们想要映射到 l1 并且在该映射内部,映射到 l2,这意味着我们考虑每个列表中的所有元素对,就像这样:

l1.map(x => l2.map(y => (x,y))

不过,这不太对,因为我们现在有一个 List[List[((String, String),(String,String))]]——我们需要平面映射:

l1.flatMap(x => l2.map(y => (x,y)))

现在我们必须过滤以保留我们想要的配对并整理:

l1.flatMap(x => l2.map(y => (x,y)))
  .filter{ case ((_,y),(b,_)) => y == b }
  .map {case ((x, _),(_,c)) => (x,c) }

这给了我们

List((Dan,3), (Dan,1), (Dan,2), (Bart,1))

这有点难看,所以我们可以稍微整理一下——让我们在原始 flatmap 中过滤 l2 并在那里构建结果,所以我们不必玩弄元组的元组:

l1.map{ case (x,y) => 
    l2.filter{ case (b, _) => y == b}
      .map{ case (_, c) => (x, c)} }

这是更容易阅读 for 理解的情况之一:

for {
  (x, y) <- l1
  (b, c) <- l2
  if y == b
} yield (x,c)

关于Scala - 通过公共(public)元素合并两个元组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50204288/

相关文章:

java - 使用LinkedList的迭代器打印值,在java中不断陷入无限循环

MySQL 查询 - 如何使用 GROUP BY 和 WHERE 条件获取 SUM 并使用 LEFT OUTER JOIN?

php - 我可以使用 GROUP BY (MySql) 选择最短的字段名称吗

mysql - 计算某个属性中具有相同值的元组实例的数量

mysql - 无法隔离 Scala 批量数据加载应用程序中的 JDBC 内存泄漏

Eclipse Scala IDE - 缺少 X 所需的类文件

Java同步死锁?

scala - sbt 总是在 CI 中重新编译整个项目,即使有缓存?

viewpager fragment 中的 Android 列表

python - 如何将不同的元素添加到列表中的列表中? python 3