迭代集合并找到多个值而不是1的更好方法(Better way to iterate on a collection and find multiple values instead of 1)

编程入门 行业动态 更新时间:2024-10-15 06:18:26
迭代集合并找到多个值而不是1的更好方法(Better way to iterate on a collection and find multiple values instead of 1)

我有以下用例,其中我在同一个集合上多次迭代,每次我在该集合中找到不同的项目。

class Foo(policyToData: Map[String, MyClass]){ val milk: Option[MyClass] = policyToData.values.find(_.`type` == Milk) val meat: Option[MyClass] = policyToData.values.find(_.`type` == Meat) val bread: Option[MyClass] = policyToData.values.find(_.`type` == Bread) val other: List[MyClass] = policyToData.values.filter(_.`type` == Other).toList }

有没有更好的方法呢? 一次迭代?

I have the following use case, in which I am iterating multiple times on the same collection, and every time I find a different item in that collection.

class Foo(policyToData: Map[String, MyClass]){ val milk: Option[MyClass] = policyToData.values.find(_.`type` == Milk) val meat: Option[MyClass] = policyToData.values.find(_.`type` == Meat) val bread: Option[MyClass] = policyToData.values.find(_.`type` == Bread) val other: List[MyClass] = policyToData.values.filter(_.`type` == Other).toList }

Is there a better way to do it? with one iteration?

最满意答案

如果它是一个大型集合,折叠到地图意味着您只构建感兴趣的集合。

scala> case class C(name: String) defined class C scala> val cs = List(C("milk"),C("eggs"),C("meat")) cs: List[C] = List(C(milk), C(eggs), C(meat)) scala> cs.foldLeft(Map.empty[String,C]) { | case (m, c @ C("milk" | "meat")) if !m.contains(c.name) => m + (c.name -> c) | case (m, _) => m } res5: scala.collection.immutable.Map[String,C] = Map(milk -> C(milk), meat -> C(meat))

然后

scala> val milk = res5("milk") milk: C = C(milk) scala> val bread = res5.get("bread") bread: Option[C] = None

原来的groupBy解决方案被删除了,因为有人评论说它做了额外的工作,但事实上它是一个简单的表达,如果创建中间列表列表是好的。

scala> cs.groupBy(_.name) res0: scala.collection.immutable.Map[String,List[C]] = Map(meat -> List(C(meat)), eggs -> List(C(eggs)), milk -> List(C(milk))) scala> res0.get("milk").map(_.head) res1: Option[C] = Some(C(milk)) scala> res0.get("bread").map(_.head) res2: Option[C] = None

要么

scala> cs.filter { case C("milk" | "meat") => true case _ => false }.groupBy(_.name) res4: scala.collection.immutable.Map[String,List[C]] = Map(meat -> List(C(meat)), milk -> List(C(milk)))

If it's a large collection, folding into a map means you only build the collection of interest.

scala> case class C(name: String) defined class C scala> val cs = List(C("milk"),C("eggs"),C("meat")) cs: List[C] = List(C(milk), C(eggs), C(meat)) scala> cs.foldLeft(Map.empty[String,C]) { | case (m, c @ C("milk" | "meat")) if !m.contains(c.name) => m + (c.name -> c) | case (m, _) => m } res5: scala.collection.immutable.Map[String,C] = Map(milk -> C(milk), meat -> C(meat))

then

scala> val milk = res5("milk") milk: C = C(milk) scala> val bread = res5.get("bread") bread: Option[C] = None

The original groupBy solution was deleted because someone commented that it does extra work, but in fact it's a straightforward expression, if creating the intermediate Map of Lists is OK.

scala> cs.groupBy(_.name) res0: scala.collection.immutable.Map[String,List[C]] = Map(meat -> List(C(meat)), eggs -> List(C(eggs)), milk -> List(C(milk))) scala> res0.get("milk").map(_.head) res1: Option[C] = Some(C(milk)) scala> res0.get("bread").map(_.head) res2: Option[C] = None

or

scala> cs.filter { case C("milk" | "meat") => true case _ => false }.groupBy(_.name) res4: scala.collection.immutable.Map[String,List[C]] = Map(meat -> List(C(meat)), milk -> List(C(milk)))

更多推荐

本文发布于:2023-08-02 20:45:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1381929.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多个   而不是   迭代   方法   iterate

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!