【问题标题】:Scala count number of times function returns each value, functionallyScala count 函数返回每个值的次数,功能上
【发布时间】:2018-06-27 03:26:16
【问题描述】:

我想计算一个函数f在应用于给定列表l时返回其范围内的每个值(0f_max,包括)的次数,并将结果返回为一个数组,在 Scala 中。

目前,我完成如下:

 def count (l: List): Array[Int] = {
    val arr = new Array[Int](f_max + 1)
    l.foreach {
      el => arr(f(el)) += 1
    }
    return arr
  }

所以arr(n)f 在应用于l 的每个元素时返回n 的次数。但是,这是可行的,它是命令式的,我想知道是否有一种干净的方法可以纯粹地从功能上做到这一点。

谢谢

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    如何更通用的方法:

    def count[InType, ResultType](l: Seq[InType], f: InType => ResultType): Map[ResultType, Int] = {
      l.view                              // create a view so we don't create new collections after each step
        .map(f)                           // apply your function to every item in the original sequence
        .groupBy(x => x)                  // group the returned values
        .map(x => x._1 -> x._2.size)      // count returned values
    }
    
    val f = (i:Int) => i
    count(Seq(1,2,3,4,5,6,6,6,4,2), f)
    

    【讨论】:

    • 非常小的改进:.map(x => x._1 -> x._2.size) 可以是.mapValues(_.size)
    【解决方案2】:
    l.foldLeft(Vector.fill(f_max + 1)(0)) { (acc, el) =>
      val result = f(el)
      acc.updated(result, acc(result) + 1)
    }
    

    或者,性能和外部纯度的良好平衡是:

    def count(l: List[???]): Vector[Int] = {
      val arr = l.foldLeft(Array.fill(f_max + 1)(0)) { (acc, el) =>
        val result = f(el)
        acc(result) += 1
      }
      arr.toVector
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-06
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      • 2014-07-30
      • 1970-01-01
      • 2021-12-21
      • 2012-02-16
      • 2020-05-24
      相关资源
      最近更新 更多