简体   繁体   中英

Transforming Map[String, Iterator[Int]] to Iterator[Map[String, Int]]

I've run into a bit of a problem. I need to convert the types

Map[String, Iterator[Int]] -> Iterator[Map[String, Int]]

My current approach at solving this problem is by using a recursive function:

def Inverter(input: Map[String, Iterator[Int]], output: Iterator[Map[String, Int]]) = {
  val inversion: Map[String, Int] = input.flatMap {case (symbol, iterator) => iterator.hasNext match {
    case true => Some((symbol,iterator.next))
    case false => None
  }}
  inversion.size match {
    case 0 => output
    case _ => Inverter(input,  output ++ Iterator(inversion))
  }
} 

This code solves the problem, but is too slow. I think it has something to do with the ++ call being slow. Is there any way I can cons elements onto the head of an Iterator like I can a List in constant time? If not, can anyone come up with a good workaround?

def invert(input: Map[String, Iterator[Int]]) =
  Iterator.continually(input.collect { 
    case (key, it) if it.hasNext => (key, it.next)
  }).takeWhile(_.nonEmpty)

Some explanation:

This part: input.collect { case (key, it) if it.hasNext => (key, it.next) } takes a single element from every iterator in the input map and creates a Map[String,Int] . Now, simply apply this operation on the input map continually, until we exhaust all the iterators.

It's a little tricky, because iterators are inherently mutable and we are relying on side effects of the collect invocation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM