Reputation:
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
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:
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
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
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