Reputation: 51
i have 2 list in scala as input. i want to compare corresponding element of both the list and in output give the score as list of two elements . elements showing sum of times the comparing element of one list was greater than other.
input:
List(1, 2, 3, 4, 7, 9)
List(0, 1, 2, 1, 1, 4)
output:
List(6,0)
as the elements of first list were six times greater than elements of second list.
Input :
List(17, 28, 30)
List(99, 16, 8)
output:
List(2,1)
I am new to scala i know this can be easily done by applying a for loop till the length of list and increasing the counter.But I am looking for a one liner solution in scala to leverage its functional programming paradigm
Upvotes: 1
Views: 358
Reputation: 27421
Counting the number of times one value is greater than the other is a one-liner:
a.zip(b).count{ case (a, b) => a > b }
If you want to result in the form you said, it takes another statement, but you can put it on the same line :)
{val c = a.zip(b).count{ case (a, b) => a > b }; (c, a.length - c)}
If you really need a single statement for your result, you need to use foldLeft
like the other solutions, but it is likely to take more than one line!
Upvotes: 1
Reputation: 51271
I am looking for a one liner solution
It kind of depends on how you count the lines. This can be expressed all on one line, but it's easier to read this way.
listA.zip(listB).foldLeft(List(0,0)){ case (List(gt,lt),(a,b)) =>
if (a>b) List(gt+1, lt)
else if (a<b) List(gt, lt+1)
else List(gt, lt)
}
Upvotes: 3
Reputation: 31252
You might want to use recursive function to compare each element in fp style which recursively computes sum at at point.
Another approach (in scala) would be zip them together and compare each row of elements.
Example:
def getScores(score1: List[Int], score2: List[Int]) = {
val scoresComapred = score1.zip(score2).map {
case (s1, s2) if s1 > s2 => (1, 0)
case (s1, s2) if s1 == s2 => (0, 0)
case (s1, s2) if s2 > s1 => (0, 1)
}
val (finalScore1, finalScore2) =
scoresComapred.foldLeft((0, 0)) { (a, b) => (a._1 + b._1, a._2 + b._2) }
List(finalScore1, finalScore2)
}
val score1 = List(1, 2, 3, 4, 7, 9, 10)
val score2 = List(0, 1, 2, 1, 1, 4)
println(getScores(score1, score2)) //List(6, 0)
println(getScores(List(17, 28, 30), List(99, 16, 8))) //List(2, 1)
Note: zip
takes only as much elements are in first collection at max.
def zip[A1 >: A, B, That](that: GenIterable[B])(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = {
val b = bf(repr)
val these = this.iterator
val those = that.iterator
while (these.hasNext && those.hasNext)
b += ((these.next(), those.next()))
b.result()
}
Related: Scala - Two Lists to Tuple List
Upvotes: 0