【问题标题】:Converting two lists to type : List[List[scala.collection.immutable.Map[String,String]]]将两个列表转换为类型:List[List[scala.collection.immutable.Map[String,String]]]
【发布时间】:2016-01-05 23:51:39
【问题描述】:

有两个列表:

 val list1 : List[List[(String, String)]] = List(List("1" -> "a" , "1" -> "b"))
                                                  //> list1  : List[List[(String, String)]] = List(List((1,a), (1,b)))
 val list2 : List[List[(String, String)]] = List(List("2" -> "a" , "2" -> "b"))
                                                  //> list2  : List[List[(String, String)]] = List(List((2,a), (2,b)))
 //Expecting
 val toConvert = List(List(Map("1" -> "a" , "2" -> "b"), Map("1" -> "b" , "2" -> "a")))

正在尝试将这些列表转换为类型:

 List[List[scala.collection.immutable.Map[String,String]]] = Lis
                                                  //| t(List(Map(1 -> a, 2 -> b), Map(1 -> b, 2 -> a)))

使用此代码:

val ll = list1.zip(list2).map(m => List(m._1.toMap , m._2.toMap))

但地图条目不见了:

 List[List[scala.collection.immutable.Map[String,String]]] = List(List(
                                                  //| Map(1 -> b), Map(2 -> b)))

如何将 list1,list2 转换为包含值的类型 List[List[scala.collection.immutable.Map[String,String]]](List(Map(1 -> a, 2 -> b), Map(1 -> b, 2 -> a)))

更新:

逻辑:Map("1" -> "a" , "2" -> "b")

使用 zip 函数组合每个列表:

  val p1 : List[(List[(String, String)], List[(String, String)])] = list1.zip(list2);

将新创建的 List 的每个元素转换为 Map,然后添加到新创建的 List 中:

val p2 = p1.map(m => List(m._1.toMap , m._2.toMap))

【问题讨论】:

  • 获取第一张地图背后的逻辑是什么:Map("1" -> "a" , "2" -> "b")
  • @Filippo 请查看更新,这是您的意思吗?数据背后没有真正的意义,我只是把收集方法当作一种学习练习。
  • 对发布的答案有何评论?
  • @Filippo 我接受了你的回答...

标签: list scala


【解决方案1】:

如何将list1list2转换成List[List[Map[...

List[List[(String, String)]] 类型开始,我们希望得到List[List[Map[String, String]]] 类型。

内部类型

我们想要的内部类型是Map[String, String]。正如我在 cmets 中所问的那样,我并不完全理解构造这个 Map 的预期逻辑,所以我假设你想从一个元组列表中创建一个 Map[String, String] List[(String, String)]

当使用.toMap 创建Map 时,具有相同keykey-value 元素将被覆盖,我们可以从b += x 在其实现中清楚地看到:

  def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U] = {
    val b = immutable.Map.newBuilder[T, U]
    for (x <- self)
      b += x
    b.result()
  }

(来源TraversableOnce.scala

所以我们用来创建List[(String, String)]的逻辑将决定生成的Map[String, String]

列表的外部列表

使用 zip 函数合并每个列表

type A = List[(String, String)]
val list12: List[(A, A)] = list1 zip list2

压缩list1list2 为我们提供了一个元组列表,但我们想要的类型实际上是一个元组列表的列表:List[List[(A, A)]]

在您的示例中,您将该类型映射到列表m =&gt; List(...)。这是关键部分。让我将其分成两部分以使其更清晰:

list12.map(m => List(m._1 , m._2)).map(_.map(_.toMap))

让我们将其提取到一个单独的函数中:

def keyPart: ((A, A)) => List[A] = { case (l1, l2) => List(l1, l2) }
val resultNotExpected = list12.map(keyPart).map(_.map(_.toMap))

结果当然和你的问题一样:

resultNotExpected == List(List(Map("1" -> "b"), Map("2" -> "b")))

“关键部分”

在您的问题中,您提到预期结果为:

List(List(Map("1" -> "a", "2" -> "b"), Map("1" -> "b", "2" -> "a")))

我仍然不明白你对现在提取的 keyPart 函数的逻辑,所以我会给你我的……当然过于复杂了:

  val resultExpected = list12.map { case (l1, l2) => List(l1, l2) }
    .map(_.map(_.zipWithIndex)).map(_.zipWithIndex)
    .map(_.map { case (l, i) => l.map { case ((k, v), j) => (k, v, i, j) } }).map(_.flatten)
    .map(_.groupBy { case (k, v, i, j) => i == j }).map(_.values.toList)
    .map(_.map(_.map { case (k, v, _, _) => k -> v }.sorted).sortBy(_.head._2))
    .map(_.map(_.toMap))

scala> resultExpected == List(List(Map("1" -> "a", "2" -> "b"), Map("1" -> "b", "2" -> "a")))
Boolean = true

也许你更了解keyPart中要实现的逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 2016-09-27
    • 2021-01-13
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多