Monday, March 15, 2010

Unzip

_ Scala 2.8 only tip _

Unzip is a handy companion to partition.
- Partition divides a traversable into two traversables by a boolean predicate.
- Unzip divides a traversable into two by dividing each element into two parts (each becomes an element in one traversable). If an element is a Tuple2 then each tuple is divided into two otherwise a function is required to divide an element into two.

  1. // basic usage
  2. scala> List((1,2),(2,3)).unzip
  3. res2: (List[Int], List[Int]) = (List(1, 2),List(2, 3))
  4. /* 
  5. tuples can be of different types 
  6. and the resulting traversables reflect the differing types
  7. */
  8. scala> List((2,"a"),(3,"b")).unzip
  9. res3: (List[Int], List[java.lang.String]) = (List(2, 3),List(a, b))
  10. // Maps are Traversable[Collection] so unzip works with them
  11. scala> Map(1 -> 2, 3 -> 4).unzip
  12. res1: (scala.collection.immutable.Iterable[Int], scala.collection.immutable.Iterable[Int]) = (List(1, 3),List(2, 4))
  13. // Of course sets result in sets and duplicates are collected to a single element
  14. scala> Set((1,2),(2,2)).unzip
  15. res7: (scala.collection.immutable.Set[Int], scala.collection.immutable.Set[Int]) = (Set(1, 2),Set(2))
  16. /*
  17. Arbitrary elements can be unziped if a method is provided to decompose each element
  18. */
  19. scala> List("one word""another word").unzip {e => (e takeWhile {_ != ' '}, e dropWhile {_ != ' '})} 
  20. res6: (List[String], List[String]) = (List(one, another),List( word,  word))
  21. /*
  22. The following shows the same function 
  23. applied with map.  It results in a single
  24.  list of Tuples rather than two lists of single elements
  25.  */
  26. scala> List("one word""another word").map {e => (e takeWhile {_ != ' '}, e dropWhile {_ != ' '})}  
  27. res8: List[(String, String)] = List((one, word), (another, word))

1 comment:

  1. More compact version using span could be:


    List("one word", "another word") unzip (_ span ' '.!=)

    ReplyDelete