过滤iretable [map [string,string]]类型的数据

时间:2019-01-21 09:53:11

标签: scala

我正在用 Scala 语言编写代码,并且具有Iterable[Map[String, String]]类型的数据,我想将其简称为:

val data = List(  
  Map("name1" -> "kislay", "name2" -> "kumar"), 
  Map("name1" -> "rupesh", "name2" -> "rupesh")
)

我希望结果采用以下格式:

val result = List(
  Map("name1" -> "kislay", "name2" -> "kumar"), 
  Map("name1" -> "rupesh", "name2" -> "")
) 

即。当name1和name2相等时,应将name2的位置留空或在该位置添加“ N / A”。

1 个答案:

答案 0 :(得分:0)

据我了解,我们有一个Map,我们想根据键的关系来更改某些值。换句话说...

Map("xyz" -> "ss1", "abc" -> "ss1")  //change this
Map("xyz" -> "N/A", "abc" -> "ss1")  //to this

...因为"ss1"是重复值,并且由于"abc""xyz"之前(词法顺序),因此我们将修改"xyz"键/值对,但保持"abc"键/值不变。

让我们的数据集更有趣。

val nameMap = Map("name1" -> "rupesh"   //keep
                 ,"name2" -> "rupesh"   //drop
                 ,"name3" -> "bo"       //keep
                 ,"name4" -> "am"       //keep
                 ,"name5" -> "bo"       //drop
                 ,"name6" -> "rupesh")  //drop

我们还将需要一个Map逆变器。

implicit class MapInverterA[K,V](m :Map[K,V]) {
  def invert :Map[V,Set[K]] =               /*from Map[K,V] to Map[V,Set[K]]*/
    m.foldLeft(Map.empty[V, Set[K]]) {
      case (acc,(k, v)) => acc + (v -> (acc.getOrElse(v,Set()) + k))
    }
}

现在我们可以创建一个倒置的nameMap,只保留我们想要的键。

val inm = nameMap.invert           //invert the Map
                 .mapValues(_.min) //keep just the 1st keys

并使用它来制作所需的mod。

nameMap.map{case (k,v) =>
    if (k == inm(v)) k -> v      //unchanged
    else             k -> "N/A"  //duplicate name
}
//res0: Map(name3 -> bo, name6 -> N/A, name2 -> N/A, name4 -> am, name1 -> rupesh, name5 -> N/A)

剩下的唯一事情就是将其应用于烦人的可迭代对象。

val result = data.map{m =>
  val inv = m.invert.mapValues(_.min)
  m.map{case (k,v) => if (k == inv(v)) k->v else k->"N/A"}
}