Scala反转拉链

时间:2014-04-05 09:33:22

标签: list scala functional-programming tuples

我想构建以下元组列表:

List(("a", 1), ("a", 2), ("a", 3), ("a", 4))

来自两个组成部分:

  1. "a"
  2. List(1,2,3,4)

  3. 已知的解决方法包括:

    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",_))
    

    但是,我认为有比这些解决方案更好的解决方案。

3 个答案:

答案 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 IterableLikezipInvert获取的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}}