sk1007
sk1007

Reputation: 571

How to create pair of keys of Map

For exemple:

mylist: Map("Start" -> 2015-05-30T00:00:00.000Z, "Daily" -> 2015-06-02T00:00:00.000Z, "Hourly" -> 2015-06-03T08:00:00.000Z, "End" -> 2015-06-04T15:00:00.000Z)

I want to output as following format:

myout: List( ("Start" -> 2015-05-30T00:00:00.000Z, "Daily" -> 2015-06-02T00:00:00.000Z), ("Daily" -> 2015-06-02T00:00:00.000Z, "Hourly" -> 2015-06-03T08:00:00.000Z), ("Hourly" -> 2015-06-03T08:00:00.000Z, "End" -> 2015-06-04T15:00:00.000) )
OR
myout: List( ("Start", "Daily"), ("Daily", "Hourly"), ("Hourly", "End"))

Case 1: Always start with "Start" key, Anything comes before "Start" key ignore it. Same for last "End" key

 mylist: Map(Hourly -> 2015-06-01T08:00:00.000Z, Start -> 2015-05-30T00:00:00.000Z, Daily -> 2015-06-02T00:00:00.000Z,  End -> 2015-06-04T15:00:00.000Z, Weekly-> 2015-06-05T00:00:00.000Z)

output should like:

  List((Start, Daily), (Daily, End))

I am looking output using scala.

Upvotes: 0

Views: 130

Answers (2)

corn_dog
corn_dog

Reputation: 181

import scala.collection.immutable.ListMap

val x = ListMap("Start" -> "x", "Daily" -> "y", "Hourly" -> "z", "End" -> "a")

x.toList.sliding(2).map( a => (a(0)._1, a(1)._1)).toList

List((Start,Daily), (Daily,Hourly), (Hourly,End))

Upvotes: 1

Beryllium
Beryllium

Reputation: 12988

Since a Map is not ordered, I have modified the input data to get stable results.

As for the 1st question

val m = 
  Map(
    "1-Start" -> "2015-05-30T00:00:00.000Z", 
    "2-Daily" -> "2015-06-02T00:00:00.000Z", 
    "3-Hourly" -> "2015-06-03T08:00:00.000Z", 
    "4-End" -> "2015-06-04T15:00:00.000Z")

The basic idea is to zip the list of keys with its own tail to get the pairs:

scala> m.keys.toList.sorted.zip(m.keys.toList.sorted.tail)
res57: List[(String, String)] = List((1-Start,2-Daily), (2-Daily,3-Hourly), 
  (3-Hourly,4-End))

To simplify the expression a "pipe forward operator" is helpful:

object PipeForwardContainer {
  implicit class PipeForward[T](val v: T) extends AnyVal {
    def |>[R](f: T => R): R = {
      f(v)
    }
  }
}

import PipeForwardContainer._

This operator provides a reference to the intermediate result. Therefore you can write:

scala> m.keys.toList.sorted |> { l => l.zip(l.tail) }
res97: List[(String, String)] = List((1-Start,2-Daily), (2-Daily,3-Hourly), 
  (3-Hourly,4-End))

As for the 2nd question

val m = 
  Map(
    "1-Hourly" -> "2015-06-03T08:00:00.000Z", 
    "2-Start" -> "2015-05-30T00:00:00.000Z", 
    "3-Daily" -> "2015-06-02T00:00:00.000Z", 
    "4-End" -> "2015-06-04T15:00:00.000Z",
    "5-Weekly"-> "2015-06-05T00:00:00.000Z")

To get the raw list you can slice out the relevant elements by index:

scala> m.keys.toList.sorted |> { l => 
  l.slice(l.indexOf("2-Start"), l.indexOf("4-End") + 1) }
res96: List[String] = List(2-Start, 3-Daily, 4-End)

Again with zip to get the pairs:

scala> m.keys.toList.sorted |> { l => 
    l.slice(l.indexOf("2-Start"), l.indexOf("4-End") + 1) 
  } |> { l => l.zip(l.tail) }
res98: List[(String, String)] = List((1-Start,2-Daily), (2-Daily,3-Hourly), 
  (3-Hourly,4-End))

Upvotes: 0

Related Questions