0

I want to count up the number of times that a function f returns each value in it's range (0 to f_max, inclusive) when applied to a given list l, and return the result as an array, in Scala.

Currently, I accomplish as follows:

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

So arr(n) is the number of times that f returns n when applied to each element of l. This works however, it is imperative style, and I am wondering if there is a clean way to do this purely functionally.

Thank you

2 Answers 2

1

how about a more general approach:

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)
Sign up to request clarification or add additional context in comments.

1 Comment

extremely minor imrovement: .map(x => x._1 -> x._2.size) can be .mapValues(_.size)
0
l.foldLeft(Vector.fill(f_max + 1)(0)) { (acc, el) =>
  val result = f(el)
  acc.updated(result, acc(result) + 1)
}

Alternatively, a good balance of performance and external purity would be:

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
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.