我有一个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.
}
^
操作的困扰,可以解决这个问题吗。
答案 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
进行完全相同的操作。但是,恕我直言,手工制作的尾递归算法更易于阅读。