使用 map 将 Map("a" -> 2, "b" -> 1) 转换为 seq("a","a","b")

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

我正在尝试通过 map 函数将 Map("a" -> 2, "b" -> 1) 转换为 seq("a","a","b"),目前我是尝试 运行 下面的代码给我想要的结果。

有没有更聪明的方法来做到这一点?可能是通过地图功能的更好方法?

    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)
    }

你可以这样做: 使用 GenTraversableFactory def fill[A](n: Int)(elem: => A): CC[A] 的 fill 方法 从 fill 的定义我们可以看出它需要一个整数和一个元素。整数表示我们需要填充给定元素的次数。

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)
}

希望对您有所帮助!!!

如果你想避免 tuple._1 和 tuple._1 你可以使用下面的方法。

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)
}

我不确定你的数据到底是什么形状。问题的那部分有点不清楚。

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

确实是一个Map。而

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

元组中的脱糖

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

如果是前者可以这样折

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))

此处res将是List('a', 'a', 'b')

这里发生的事情是,我们从一个空累加器开始,遍历 Map 的 key-value 对,创建一个重复给定键、值次数的列表,并将其连接到累加器

不幸的是,如果不使用 Shapeless 之类的东西,后者会有点困难,因为在 Scala 2 中,从元组转换时类型信息会丢失。你需要用注释做一些类型的杂耍

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)
})