在scala中找到一个列表的元素的计数大于另一个列表的元素的计数

时间:2018-10-20 17:50:46

标签: scala

我在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中寻找一种线性解决方案来利用其功能编程范例

3 个答案:

答案 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()
  }

相关:Scala - Two Lists to Tuple List