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

时间:2020-10-16 12:46:08

标签: scala loops iterator higher-order-functions simplification

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

是否有更聪明的方法来做到这一点?可能是通过map函数更好的方法吗?

const arr = [{id: 123, val: 'abcd', other: 'abcd'}, {id: 123, val: 'abcd', other: 'abcd', show: true}, {id: 123, val: 'abcd', other: 'abcd', show: false}, {id: 123, val: 'abcd', other: 'abcd'}]

const result = arr.map(({ id, val, show }) => {
  const newObj = {
    id,
    val: val != null ? val : ''
  };
  if (show) {
    newObj['show'] = show;
  }
  return newObj;
});

console.log(result);

2 个答案:

答案 0 :(得分:4)

您可以执行以下操作: 从fill的定义中使用GenTraversableFactory def fill[A](n: Int)(elem: => A): CC[A]的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)
}

答案 1 :(得分:1)

我不确定您的数据的确切形状。这个问题有点不清楚。

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

确实是一张地图。而

('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的键-值对,创建一个重复给定键,值时间并将其连接到累加器的列表

不幸的是,在不使用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)
})
相关问题