加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 为什么maxBy只返回单项?

发布时间:2020-12-16 18:32:06 所属栏目:安全 来源:网络整理
导读:跟进 this question我想知道为什么Traversable [T]的maxBy返回单个值T而不是T序列(列表或类似).这看起来很常见.例如(来自上一个问题): 有关成绩的学生名单 List(Student("Mike","A"),Student("Pete","B"),Student("Paul",A))" 我想得到 List(Student("Mike"
跟进 this question我想知道为什么Traversable [T]的maxBy返回单个值T而不是T序列(列表或类似).这看起来很常见.例如(来自上一个问题):

有关成绩的学生名单

List(Student("Mike","A"),Student("Pete","B"),Student("Paul",A))"

我想得到

List(Student("Mike",A))

有没有人知道maxBy的任何标准实现,它返回一系列找到的项目?

解决方法

没有单一的命令.我所知道的最短 – 将所有东西分组,而不仅仅是作为中间体的最大值 –

xs.groupBy(f).maxBy(_._1)._2

为了提高效率,折叠是用于查找总和和最大值以及各种类似事物的通用工具.基本上,任何时候你需要在积累一些答案时跑过你的收藏,使用折叠.在这种情况下,

(xs.head /: xs.tail) {
  (biggest,next) => if (f(biggest) < f(next)) next else biggest
}

如果您不介意为每个元素重新计算两次函数,则会执行maxBy(f)

((xs.head,f(xs.head)) /: xs.tail) {
  case (scored,next) =>
    val nextscore = f(next)
    if (scored._2 < nextscore) (next,nextscore)
    else scored
}._1

将每个元素只进行一次评估.如果要保留序列,可以将其修改为

(Seq(xs.head) /: xs.tail) {
  (bigs,next) =>
    if (f(bigs.head) > f(next)) bigs
    else if (f(bigs.head) < f(next)) Seq(next)
    else bigs :+ next
}

保留列表(相应的单一评估表格留给读者练习).

最后,如果您愿意使用一些可变变量(希望隐藏在代码块中,就像我在这里一样),即使是接近最大效率的版本也不是很难管理的.

val result = {
  var bigs = xs.take(0).toList
  var bestSoFar = f(xs.head)
  xs.foreach{ x =>
    if (bigs.isEmpty) bigs = x :: bigs
    else {
      val fx = f(x)
      if (fx > bestSoFar) {
        bestSoFar = fx
        bigs = List(x)
      }
      else if (fx == bestSoFar) bigs = x :: bigs
    }
  }
  bigs
}

(这将以相反的顺序返回,顺便说一下).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读