我在scala中有2个列表作为输入。我想比较列表中的相应元素,并在输出中给出分数作为两个元素的列表。元素显示一个列表的比较元素大于其他列表的时间总和。
input:
List(1, 2, 3, 4, 7, 9)
List(0, 1, 2, 1, 1, 4)
output:
List(6,0)
第一个列表的元素比第二个列表的元素大六倍。
Input :
List(17, 28, 30)
List(99, 16, 8)
output:
List(2,1)
我对scala还是陌生的,我知道可以通过应用for循环直到列表的长度并增加计数器来轻松实现。但是,我正在scala中寻找一种线性解决方案来利用其功能编程范例
答案 0 :(得分:3)
我正在寻找一种班轮解决方案
这取决于您如何计算行数。这可以全部表达出来,但是用这种方式更容易阅读。
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)
}
答案 1 :(得分:1)
计算一个值大于另一个值的次数是单线的:
a.zip(b).count{ case (a, b) => a > b }
如果要生成您所说的形式,则需要另外一条语句,但是您可以将其放在同一行:)
{val c = a.zip(b).count{ case (a, b) => a > b }; (c, a.length - c)}
如果您的结果确实需要一个语句,则需要像其他解决方案一样使用foldLeft
,但可能需要一行以上!
答案 2 :(得分:0)
您可能想使用递归函数来比较fp样式的每个元素,这些元素以递归方式计算点的总和。
另一种方法(在scala中)是将它们压缩在一起并比较每行元素。
示例:
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)
注意: zip
最多只能容纳第一个集合中的元素。
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()
}