scala - 匹配元组中第一个引用项的第 n 个条目
问题描述
我有一个List
包含元组的元组(e:Int, a:String, b:String)
,其中e
指向将增加的 eventid,a
表示元组中第一个引用的项目并b
表示第二个。
该列表按 eventid 排序,我需要获取匹配 n 的项目的第 n 个条目。
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"))
预期的结果是
(1,W)
(1,I)
(1,P)
(1,S)
(2,A)
(4,E)
Wa
第一次出现在 eventid=10 并且应该被捕获。对于 I、P 和 S。A 出现在 eventid=20 中,b
但在 eventid=40 中再次引用,所以它应该被捕获为(2,A)
。对于 E 也是如此。
我正在尝试使用以下代码,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.
}
^
我在foldLeft
这里的操作很困难,可以解决吗?
解决方案
这应该有效。
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
. 但是,恕我直言,手工制作的尾递归算法更容易阅读。
推荐阅读
- php - 从 PHP Web 应用程序连接到本地/本地 Active Directory
- powershell - 向PowerShell中的多个地址发送电子邮件
- c++ - 运行时 C++ 数学无法按预期工作
- delphi - 调整表格大小以适合其标题
- vim - vim range .+1,$ 包含当前行,对一行影响太大
- database - Symfony:更新数据库模式以反映已删除的表
- android-studio - Flutter 应用程序在创建时出错
- amazon-web-services - 用户无权执行:rekognition:RecognizeCelebrities with a explicit deny
- python - 带字符串的压缩列表结果
- html - css属性计算不适用于视口高度