user9683185
user9683185

Reputation:

scala calculate number of occurences of an element

I have the following list as input :

val lisinputt=("banana  10",
          "apple   20",
          "apple   30",
          "banana   10",  
          "berry    10")

and I want to calculate the number of occurences for each element than sum values related to each element, hence the wanted output will be :

val listoutput=("banana  2 20",
          "apple 2  50",  
          "berry  1  10")

Any idea how to achieve this please

Upvotes: 0

Views: 100

Answers (3)

crowgers
crowgers

Reputation: 274

Both answers given are completely correct, given your original input. However, my answer is assuming your input is not restricted to the form provided.

Another way to deal with this problem is to structure your data into a tuple initially, research tuples here for more info.

For your example this will look like:

val = lisinputt = List(
    ("banana", 10),
    ("apple", 20),
    ("apple", 30),
    ("banana", 10),
    ("berry", 10))

Then using the below you can access and aggregate the lists.

val aggreagatedList = lisinputt.groupBy(_._1).map {
    case (fruit, number) => ( fruit, number.size , number.map(_._2).sum )
}

This essentially does the same thing as both other answers (look at case e => and you'll see similarities), however in both answers there is logic to modify your input so it can be aggregated.

There's a few things going on in this command that are worth explaining:

  1. Firstly groupBy applied to the lisinputt will sort by unique parameters
  2. _._1 means the first entry of all tuples (parameter for groupBy)
  3. case (fruit, member) is assigning vars to the 1st and 2nd element in your tuple ( you can specify this as one variable but that makes the accessors less readable
  4. the => means for each unique (groupBy above specifies this) case return a tuple entry of which the first element is the name, the 2nd is the occurrences and the 3rd is summing the all 2nd entries of matching fruit in the original tuple.

Hope this helps, also I'm learning as well so if there are mistakes in the solution or my understanding of these functions I'm only happy to accept corrections.

Upvotes: 1

Puneeth Reddy V
Puneeth Reddy V

Reputation: 1568

You can expected output like this

val listInput=("banana  10",
  "apple   20",
  "apple   30",
  "banana   10",
  "berry    10")
val result = listInput.productIterator.toList.map(_.toString.split("\\s+")).groupBy(e=> e.apply(0)).collect{
  case e=> (e._1, e._2.size, e._2.map(_.apply(1).toInt).sum)
}
//result: scala.collection.immutable.Iterable[(String, Int, Int)] = List((banana,2,20), (apple,2,50), (berry,1,10))

Upvotes: 0

Ramesh Maharjan
Ramesh Maharjan

Reputation: 41957

You can do something like below

val lisinputt=("banana  10",
  "apple   20",
  "apple   30",
  "banana   10",
  "berry    10")

lisinputt.productIterator.toList
  .map(x => {val splitted = x.toString.split("\\s+"); (splitted(0), 1, splitted(1))})
  .groupBy(_._1)
  .mapValues(x => (x.map(_._2.toInt).sum, x.map(_._3.toInt).sum))
  .map(x => Array(x._1, x._2._1, x._2._2).mkString(" "))
  .foreach(println)

which should give you

banana 2 20
apple 2 50
berry 1 10

Upvotes: 1

Related Questions