有没有人知道将以下inputList转换为下面所需的输出列表的好方法?
我想要创造的功能
def transformList(input:List[(String,String)]):List[(String,String)] = ???
输入
val inputList = List(
("class","testClass1"),
("class","testClass2"),
("id","testId1"),
("class","testClassRepeat"),
("class","testClassRepeat"),
("id","testId2"),
("href","testHref1")
)
期望的输出
List(
("class","testClass1 testClass2 testClassRepeat testClassRepeat"),
("id","testId1 testId2"),
("href","testHref1")
)
我有一个解决方案,但我不认为我是以一种好/有效的方式做到这一点。我目前使用的解决方案是:
谢谢, 菲尔
答案 0 :(得分:9)
def f(xs: List[(String, String)]): Map[String, List[String]] =
xs.foldRight(Map.empty[String, List[String]]){
(elem: (String, String), acc: Map[String, List[String]]) =>
val (key, value) = elem
acc.get(key) match {
case None => acc + (key -> List(value))
case Some(ys) => acc.updated(key, value :: ys)
}
}
scala> f(inputList)
res2: Map[String,List[String]] = Map(
href -> List(testHref1),
id -> List(testId1, testId2),
class -> List(testClass1, testClass2, testClassRepeat, testClassRepeat)
)
答案 1 :(得分:5)
也许groupBy()
正是您要找的?
scala> inputList.groupBy(_._1)
res0: Map[String,List[(String, String)]] = Map(
href -> List((href,testHref1)),
class -> List((class,testClass1), (class,testClass2), (class,testClassRepeat), (class,testClassRepeat)),
id -> List((id,testId1), (id,testId2))
)
在我们处理元组列表的同时清理元组列表也非常简单,例如。
scala> inputList.groupBy(_._1).map(kv => (kv._1, kv._2.map(_._2)))
res1: Map[String,List[String]] = Map(
href -> List(testHref1),
class -> List(testClass1, testClass2, testClassRepeat, testClassRepeat),
id -> List(testId1, testId2)
)
答案 2 :(得分:4)
您可以使用groupBy,可以在一行中完成。
scala> inputList.groupBy(_._1).
map{ case (key, value) => (key, value.map(_._2).mkString(" "))}.toList
res0: List[(String, String)] = List(
(href,testHref1),
(class,testClass1 testClass2 testClassRepeat testClassRepeat),
(id,testId1 testId2)
)
答案 3 :(得分:2)
您可以对已排序的集合使用foldLeft:
def transformList(input:List[(String,String)]):List[(String,String)] =
input
.sortBy(_._1)
.foldLeft(List[(String, String)]()) {
case ((xn,xv)::xs, (name, value)) if xn==name => (xn, xv + " " + value)::xs
case (xs, item) => item::xs
}
答案 4 :(得分:2)
另一种理解但同时使用groupBy
的方法(参见@hezamu):
val m =
for { (k, xs) <- inputList.groupBy(_._1)
s = xs.map(_._2).mkString(" ")
}
yield k -> s
然后
m.toMap
答案 5 :(得分:2)
您可以将groupBy
与for comprehension
一起使用,使代码更符合关系SQL概念,其中您需要的结果类似于键上的Group By
,然后转换分组结果,在这种情况下连接字符串:
def transformList(input:List[(String,String)]):List[(String,String)] = {
(for {
// Return the generator for key-values of grouped result
(k, v) <- input.groupBy(y => y._1)
// For every list in the grouped result return the concatenated string
z = v.map(_._2).mkString(" ")
} yield k -> z)
.toList
}