Scala学习曲线的延续
我有两个对象列表。我需要将这些列表合并为一个列表,同时应用具有匹配pares的逻辑。
例如,这里有两个列表:
case class test(int: Int, str: String)
val obj1 = test(1, "one")
val obj2 = test(2, "two")
val list1 = List(obj1, obj2)
val obj3 = test(2, "Another two")
val obj4 = test(4, "four")
val list2 = List(obj1, obj2)
我需要的是
List(test(1, "one old"), test(2, "Another two updated"), test(4, "four new"))
粗略地说,我可以用一种老式的方式迭代所有元素,并在那里进行所有转换,但这不是“Scala方式”(我猜)。
我试着用foldLeft
接近它,但被卡住了。以下是我不工作的地方:
list1.foldLeft(list2) { (a:test, b:test) =>
b.int match {
case a.int => {
//Apply logic and create new object
}
}
}
更新现在我做了两个步骤:
var tasks : Seq[ChecklistSchema.Task] = left.tasks.map((task:ChecklistSchema.Task) =>
right.tasks.find(t => t.groupId == task.groupId) match {
case Some(t: ChecklistSchema.Task) => t
case _ => {
task.status match {
case TaskAndValueStatus.Active => task.copy(status = TaskAndValueStatus.Hidden)
case _ => task
}
}
}
)
tasks = tasks ++ right.tasks.filter((t:ChecklistSchema.Task) => !tasks.contains(t))
一定有更好的办法!
谢谢
4条答案
按热度按时间dluptydi1#
val list2 = List(obj3, obj4)
。以下是我的方法:
1.将“旧”应用于所有list1条目
1.为list2创建一个Map,以便有效地检查(在下一个方法中)是否有重复的值来自list2。(
breakOut
在这里指示编译器使用最合适的工厂来构建它。更多信息,请访问https://stackoverflow.com/a/7404582/4402547)applyLogic
决定如何称呼一个非旧测试(“新”或“更新”)1.将它们放在一起,索引上的
groupBy
,applyLogic
和排序(可选)。iih3973s2#
我不知道这个解决方案是否是“Scala方式”,但它使用了
foldLeft
。4uqofj5v3#
map更新新值,groupBy更新distinct值
gcuhipw94#
我建议使用 Set 而不是List,并像下面的代码一样覆盖你的case类equals函数:
要知道在组合中使用集合的顺序很重要,并且会给予不同的结果。
输出是这样的:Set(test(2,Another two),test(4,four),test(1,one))
你也可以保留你的列表,做三个额外的转换,像这样: