第n个匹配元组中第一个引用项目的条目

时间:2019-09-05 13:11:11

标签: scala

我有一个List,其中包含元组(e:Int, a:String, b:String),其中e表示将增加的eventid,a表示元组中第一个引用的项目,{{ 1}}代表第二个。

列表在eventid上排序,我需要获取与n相匹配的项的第n个条目。

b

预期结果是

val ad = List(( 10 ,"W","A"),( 20 ,"W","E"),( 30 ,"I","W"),( 40 ,"A","E"),( 50 ,"P","E"),
( 60 ,"S","A"),( 70 ,"A","P"),( 80 ,"A","I"),( 100 ,"A","S"),( 110 ,"I","S"),
( 120 ,"A","N"),( 130 ,"E","N"))

W在eventid = 10上首次出现在(1,W) (1,I) (1,P) (1,S) (2,A) (4,E) 中,应该将其捕获。对于I,P和S同样。A在a中针对eventid = 20出现,但首先在eventid = 40中再次引用,因此应将其捕获为b。对于E同样。

我正在尝试使用(2,A)使用以下代码,但会收到错误和错误的结果。

foldLeft

错误:

val t = ( 1 until ad.size).map {
  p => {
    ad.foldLeft((List.empty[(Int, String)], Map[String, Int]().empty, Map[String, Int]().empty)) {
      case ((a, b, c), x) => {

        (a, x+ ( b, (b.getOrElse(x._2, 0) + 1),  x + (x._3 , (b.getOrElse(x._3, 0) + 1))
      }
    }._1
  }
}

我在这里遇到Error:(9, 8) ')' expected but '}' found. } ^ 操作的困扰,可以解决这个问题吗。

1 个答案:

答案 0 :(得分:3)

这应该有效。

final case class Entry(eventId: Int, a: String, b: String)

def getNthEntry(data: List[Entry]): Map[String, Int] = {
  def getPlusOne(map: Map[String, Int], key: String): (String, Int) =
    key -> (map.getOrElse(key, default = 0) + 1)

  @annotation.tailrec
  def loop(remeaining: List[Entry], acc: Map[String, Int], bCount: Map[String, Int]): Map[String, Int] =
    remeaining match {
      case Nil =>
        acc

      case Entry(_, a, b) :: xs =>
        val newAcc = 
          if (acc.contains(a))
            acc
          else
            acc + getPlusOne(map = bCount, key = a)

        val newBCount =
          bCount + getPlusOne(map = bCount, key = b)

        loop(remeaining = xs, newAcc, newBCount)
    }

  loop(remeaining = data, acc = Map.empty, bCount = Map.empty)
}

注意:从技术上讲,您可以使用foldLeft进行完全相同的操作。但是,恕我直言,手工制作的尾递归算法更易于阅读