gpt4 book ai didi

scala - 如何在丢弃集合的某些元素时进行分组

转载 作者:行者123 更新时间:2023-12-03 16:44:35 24 4
gpt4 key购买 nike

我想根据类型 Option 的鉴别器将序列分组为序列图,类似于 groupBy 的结果方法但其中值导致 None被丢弃。或者,按 PartialFunction 分组判别器并丢弃未定义偏函数的那些。

下面是一个具体的例子:

我有一组名称和一组命名空间。一些(但不是全部)名称属于有效的命名空间,我想将那些名称分组到 Map 中,丢弃那些不存在的名称。

目前我的解决方案相当于:

val names = List("ns1.foo", "ns2.bar", "ns2.baz", "froznit")
val namespaces = List("ns1", "ns2")

def findNamespace(n: String): Option[String] = namespaces.find(n.startsWith)

val groupedNames = names.groupBy(findNamespace).collect {
case (Some(ns), name) => (ns, name)
}
// Map((ns1,List(ns1.foo)), (ns2,List(ns2.bar, ns2.baz)))

我对这个解决方案的担忧是,使用 names.groupBy(findNamespace) ,我正在创建一个中间 Map,其中包含我不关心的所有名称,在键 None 下.如果我丢弃的名字数量变多,这个解决方案就变得不那么有吸引力了。

不过,我试图避免这种情况有点像火车事故:
val groupedNames =
names.
map(n => (findNamespace(n), n)).
collect({ case (Some(ns), n) => (ns, n) }).
groupBy(_._1).
map({ case (ns, names) => (ns, names.map(_._2)) })

如果你用更聪明的方式解决这个问题,它会是什么?

编辑:理想情况下,解决方案应该只调用 findNamespace(name)每个名称一次,仅使用 Option[String] 构建 Map值,无需调用单独的 hasNamespace(name)谓词。

最佳答案

您可以使用 foldLeft:

val gn = names.foldLeft(Map[String, List[String]]()){ case (acc, name) =>
findNamespace(name) match {
case Some(ns) => acc + (ns -> (name :: acc.get(ns).getOrElse(Nil)))
case _ => acc
}
}

假设顺序无关紧要,否则您可以使用 gn.mapValues(_.reverse) 反转值.

关于scala - 如何在丢弃集合的某些元素时进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6010017/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com