我想构建以下元组列表:
List(("a", 1), ("a", 2), ("a", 3), ("a", 4))
来自两个组成部分:
"a"
List(1,2,3,4)
已知的解决方法包括:
List(1,2,3,4) zip Stream.continually("a") map { _.swap }
List(1,2,3,4).zipAll("a", "for missing values", "a")
List(1,2,3,4).map(("a",_))
但是,我认为有比这些解决方案更好的解决方案。
答案 0 :(得分:1)
刚试过Scala工作表:
List(1,2,3,4) map (v => ("a", v)) //> res0: List[(String, Int)] = List((a,1), (a,2), (a,3), (a,4))
它出了什么问题?
答案 1 :(得分:1)
你对“更好”的定义是什么? 这是一些可能的解决方案:
scala> (List.fill(4)("a"), List(1, 2, 3, 4)).invert
res0: List[(String, Int)] = List((a,1), (a,2), (a,3), (a,4))
scala> List(1, 2, 3, 4).map{ ("a", _) }
res1: List[(String, Int)] = List((a,1), (a,2), (a,3), (a,4))
答案 2 :(得分:1)
AFAIK在标准的Scala集合库中没有直接实现反向zip方法。
但是,如果您查看List
IterableLike
从zipInvert
获取的import language.higherKinds
import collection.GenIterable
import collection.generic.CanBuildFrom
implicit class ZipInvert[A,CC[X] <: GenIterable[X]](coll: CC[A]) {
def zipInvert[A1 >: A, B, That](that: GenIterable[B])(implicit bf: CanBuildFrom[CC[A], (B, A1), That]): That = {
val b = bf(coll)
val these = coll.iterator
val those = that.iterator
while (these.hasNext && those.hasNext)
b += ((those.next, these.next))
b.result
}
}
val numberList = List.range(1,5)
numberList zipInvert Stream.continually("a")
,您可以轻松定义自己的scala -i
扩展方法:
scala -i ZipInvert.scala
Loading ZipInvert.scala...
import language.higherKinds
import collection.GenIterable
import collection.generic.CanBuildFrom
defined class ZipInvert
numberList: List[Int] = List(1, 2, 3, 4)
res0: List[(String, Int)] = List((a,1), (a,2), (a,3), (a,4))
...
将其粘贴到REPL中以执行它或将其粘贴到文件中并使用List
执行它:
$ scala
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.
scala> List.tabulate(4)(index => ("a",index+1))
res0: List[(String, Int)] = List((a,1), (a,2), (a,3), (a,4))
scala>
上面的示例是使用Scala 2.10.4编译的。
如果您想要根本没有中间收集,例如为避免进一步的内存开销,请使用{{1}}随播广告对象:
{{1}}