如何从 Scala 中的映射键中获取值的常见元素?

Posted

技术标签:

【中文标题】如何从 Scala 中的映射键中获取值的常见元素?【英文标题】:How to get common elements of values from map keys in Scala? 【发布时间】:2020-04-06 06:13:49 【问题描述】:

通过一系列 Scala 练习来更好地理解高阶函数。我遇到过这个问题。我有以下地图:

val keyValues = Map("a" -> List(1, 3), "b" -> List(1), "c" -> List(1,3,4,5))

我怎样才能得到一个包含所有 3 个键值列表的公共元素的列表,这将是:

val common = List(1)

我怎样才能得到一个包含所有键值元素的列表:

val all = List(1,3,4,5)

我是函数式编程的新手,所以如果有人能帮助我理解它背后的逻辑,我会非常感激。提前致谢!

【问题讨论】:

【参考方案1】:

恕我直言,Sets 是解决此类问题的绝佳数据结构。

val keyValues = Map("a" -> List(1, 3), "b" -> List(1), "c" -> List(1,3,4,5))

val valuesAsSets = keyValues.valuesIterator.map(_.toSet).toList

val all = valuesAsSets.foldLeft(Set.empty[Int])(_ | _)
val all = valuesAsSets.foldLeft(Set.empty[Int])  case (acc, set) => acc.union(set) 
// all: Set[Int] = Set(1, 3, 4, 5)

val common = all.filter(elem => valuesAsSets.forall(set => set.contains(elem)))
// common: Set[Int] = Set(1)

【讨论】:

嘿,谢谢您的回答!你能向我解释一下这条线的作用:(Set.empty[Int])(_ | _) 吗? @hispaniccoder Set.emptyInt] 创建一个空集作为 fold left 的第一个参数,它是累加器的初始值。 (_ | _) 是两个参数的函数的简写,我们在函数的第一个参数上调用| 方法union 的别名),然后传递函数的第二个参数作为union 方法的参数。在简历中,这是将所有集合连接在一起。 @hispaniccoder 让我再给你一个建议,我会把你所有的问题都转移到gitter 这是一个聊天,所以答案会更实时,会有更多的人。此外,他们对这类基本问题比 SO 更友好。 非常感谢您的建议!您是否有任何其他来源可以让我在 Scala 中找到练习以更加熟悉?我经历了 Scala 之旅,现在我正在尝试寻找更多练习来练习。 @hispaniccoder 在技术上引发了我不应该在这里回答这个问题。所以我建议你在 gitter 频道问,我很乐意在那里回答你这个问题,或者如果你问的那一刻我不在,你仍然会从很多人那里得到很多好的答案。【参考方案2】:

你可以使用intersect:

keyValues.values.reduce((l1, l2) => l1.intersect(l2))

并得到所有:

keyValues.values.map(_.toSet).reduce((s1, s2) => s1 ++ s2).toList

【讨论】:

以上是关于如何从 Scala 中的映射键中获取值的常见元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用过滤器从scala中的数据框中获取包含空值的行集

将 JSON 映射到数据模型,需要从动态键中获取嵌套的电子邮件值

「大数据」(八十九)Scala之映射和元组

Scala 集合如何从映射操作中返回正确的集合类型?

使用项目加载器scrapy获取键中的值

在配置单元中,如何获取具有键,值的子集的映射