gpt4 book ai didi

scala - 减少对象列表的最快方法

转载 作者:行者123 更新时间:2023-12-03 13:08:56 25 4
gpt4 key购买 nike

我有一个列表:

case class Person(name:String, salary:Int, cars:Int, country:String)
val a = Person("gin", 100, 2, "Ind")
val b = Person("gin", 200, 1, "Ind")
val c = Person("gin", 50, 1, "US")
val d = Person("bin", 10, 0, "US")
val e = Person("bin", 20, 2, "UK")
val f = Person("bin", 30, 5, "Ind")
val list = List(a, b, c, d, e, f)

我想根据名称和国家/地区减少上面的列表,因此输出将是

Person("gin", 300, 3, "Ind")
Person("gin", 50, 1, "US")
Person("bin", 10, 0, "US")
Person("bin", 20, 2, "UK")
Person("bin", 30, 5, "Ind")

我的解决方案是:

listBuffer.groupBy(p => p.name -> p.country).map {
case (key, persons) => key -> (persons.map(_.salary).sum, persons.map(_.cars).sum)
}.map {
case ((name, coutry), (ss, cs)) => Person(name, ss, cs, coutry)
}

对于上述问题,有没有更高效的解决方案?

最佳答案

除了 Nyavro 的建议之外,您还可以(按照降低抽象级别的顺序,从而提高效率和降低可组合性):

  1. 通过使用 persons.view.map(...).sum 或更多,避免 persons.map(...).sum 中的中间集合直接

    def sumBy[A, B](xs: Seq[A])(f: A => B)(implicit n: Numeric[B]) = 
    xs.foldLeft(n.zero) { (a, b) => n.plus(a, f(b)) }

    sumBy(persons)(_.salary)
  2. 对于这种情况,您甚至可以一次完成所有操作:

    listBuffer.foldLeft(Map.empty[(String, String), Person]) {
    (map, p) =>
    val key = (p.name, p.country)
    map.updated(key, (map.get(key) match {
    case None => p
    case Some(oldP) =>
    Person(p.name, p.salary + oldP.salary, p.cars + oldP.cars, p.country)
    })
    }
  3. 将上面的代码转换为 while 循环(除非您确实需要性能,否则不推荐)。

关于scala - 减少对象列表的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36691380/

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