如何将unzipWithIndex添加到所有有意义的Scala集合中

Mat*_*hew 1 scala scala-2.8 scala-collections

假设我有一个字符串列表,我使用zipWithIndex将其转换为元组列表:

List("a", "b", "c").zipWithIndex
res1: List[(java.lang.String, Int)] = List((a,0), (b,1), (c,2))
Run Code Online (Sandbox Code Playgroud)

我想编写一个执行反向转换的unzipWithIndex方法,即一种方法,当应用于第二个元素是前N个整数的排列的元组列表时,返回第一个元素,这些元素是以未计算的顺序排列的:

List(("c",2), ("a",0), ("b",1)).unzipWithIndex
res2: List[java.lang.String] = List(a, b, c)
Run Code Online (Sandbox Code Playgroud)

该方法应该适用于任何合适的2元组集合,其第二元素是Int类型,最好使用Pimp My Library模式.我将如何使用Scala 2.8系列进行此操作?

psp*_*psp 16

object Test {
  import collection.generic.CanBuildFrom

  class Unzip[T, CC[X] <: Traversable[X]]
    (coll: CC[(T, Int)])
    (implicit bf: CanBuildFrom[CC[(T, Int)], T, CC[T]]) {
    def unzipWithIndex: CC[T] = bf(coll) ++= (coll.toSeq sortBy (_._2) map (_._1)) result
  }

  implicit def installUnzip[T, CC[X] <: Traversable[X]]
    (coll: CC[(T, Int)])
    (implicit bf: CanBuildFrom[CC[(T, Int)], T, CC[T]]) = new Unzip[T, CC](coll)

  def main(args: Array[String]): Unit = {
    val x1 = util.Random.shuffle("abcdefgh".zipWithIndex)

    println("x1 shuffled = " + x1)
    println("x1.unzipWithIndex = " + x1.unzipWithIndex)

    val x2 = (1 to 10).toSet.zipWithIndex

    println("x2 = " + x2)
    println("x2.unzipWithIndex = " + x2.unzipWithIndex)
  }
}

% scala Test
x1 shuffled = Vector((f,5), (g,6), (c,2), (d,3), (e,4), (a,0), (h,7), (b,1))
x1.unzipWithIndex = Vector(a, b, c, d, e, f, g, h)
x2 = Set((8,8), (2,5), (3,7), (5,0), (9,4), (4,9), (6,3), (10,1), (7,6), (1,2))
x2.unzipWithIndex = Set(5, 10, 1, 6, 9, 2, 7, 3, 8, 4)
Run Code Online (Sandbox Code Playgroud)