Turning Map(“a” -> 2, “b” -> 1) into seq(“a”,“a”,“b”) using map

拟墨画扇 提交于 2021-01-20 09:43:01

问题


I am trying to turn a Map("a" -> 2, "b" -> 1) into seq("a","a","b") through the map function, Currently I am trying to run the code below giving me the desired result.

Is there a smarter way to do this? Possibly a better way through the map function?

    var multiset : Seq[T] = Seq[T]()
    var variables : Seq[T] = data.map(x => x._1).toSeq
    var variableCounts : Seq[Int] = data.map(x => x._2).toSeq
    for(x <- 0 until variables.length){
        for(y <- 0 until variableCounts(x))
            multiset = multiset :+ variables(x)
    }

回答1:


you can do something like this: Use fill method of GenTraversableFactory def fill[A](n: Int)(elem: => A): CC[A] from the definition of fill we can see that it takes an integer and an element. Integer tell how many times we need to fill the given element.

object Demo extends App {

  val x = Map("a" -> 2, "b" -> 1)

  val p: Seq[String] = x.flatMap { tuple =>
    List.fill(tuple._2)(tuple._1)
  }.toSeq

  print(p)
//output: List(a, a, b)
}

I Hope it helps!!!

If you want to avoid tuple._1 and tuple._1 you can use the following approach.

object Demo extends App {

  val x = Map("a" -> 2, "b" -> 1)

  val p: Seq[String] = x.flatMap { case (key, value) =>
    List.fill(value)(key)
  }.toSeq

  print(p)
//output: List(a, a, b)
}



回答2:


I am not sure exactly what the shape of your data is. That part is a little bit unclear from the question.

Map('a' -> 3, 'b' -> 1)

Is indeed a Map. Whereas

('a' -> 3, 'b' -> 1)

desugars in a Tuple

(('a', 3), ('b', 1))

If it is the former case you can fold like this

val m : Map[String, Int] =  Map("a" -> 2, "b" -> 1) 
val res = m.foldLeft(List[String]())((a, b) => a ++ List.fill(b._2)(b._1))

here res will be List('a', 'a', 'b')

What is going on here is that we start with an empty accumulator, iterate through the key-value pairs of the Map, create a list that repeats the given key, value times and concat it to the accumulator

The latter is unfortunately a little harder without using something like Shapeless since in Scala 2 the type information will get lost when converting from a Tuple. You need to do some type juggling with the annotations

val ml = ("a" -> 2, "b" -> 1).productIterator
ml.foldLeft(List[String]())((a, b) => b match{ 
   case (k: String, v : Int) => a ++ List.fill(v)(k)
})


来源:https://stackoverflow.com/questions/64389463/turning-mapa-2-b-1-into-seqa-a-b-using-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!