合并scala映射并根据条件更新公用密钥

时间:2019-02-13 05:08:11

标签: scala

我编写了以下代码来合并映射和更新公用密钥。有没有更好的办法写这个

stdout

这是我的测试用例

  case class Test(index: Int, min: Int, max: Int, aggMin: Int, aggMax: Int)
  def mergeMaps(oldMap: Map[Int, Test], newMap: Map[Int, Test]): Map[Int, Test] = {
    val intersect: Map[Int, Test] = oldMap.keySet.intersect(newMap.keySet)
      .map(indexKey => indexKey -> (Test(newMap(indexKey).index, newMap(indexKey).min, newMap(indexKey).max,
        oldMap(indexKey).aggMin.min(newMap(indexKey).aggMin), oldMap(indexKey).aggMax.max(newMap(indexKey).aggMax)))).toMap
    val merge = (oldMap ++ newMap ++ intersect)
    merge
  }

2 个答案:

答案 0 :(得分:2)

这里的解决方案略有不同。

def mergeMaps(oldMap :Map[Int,Test], newMap :Map[Int,Test]) :Map[Int,Test] =
  (oldMap.values ++ newMap.values)
    .groupBy(_.index)
    .map{ case (k,v) =>
      k -> v.reduceLeft((a,b) => 
          Test(k, b.min, b.max, a.aggMin min b.aggMin, a.aggMax max b.aggMax))
    }

我本可以在groupBy()后面加上mapValues(),而不是map(),但后面还有doesn't result in a pure Map

答案 1 :(得分:0)

另一个可以完成相同任务的版本。

    def mergeMaps(oldMap: Map[Int, Test], newMap: Map[Int, Test]): Map[Int, Test] = {

          (newMap ++ oldMap).map(key => {
            val _newMapData = newMap.get(key._1)
            if (_newMapData.isDefined) {
              val _newMapDataValue = _newMapData.get
              val oldMapValue = key._2
              val result = Test(_newMapDataValue.index, _newMapDataValue.min, _newMapDataValue.max,
                oldMapValue.aggMin.min(_newMapDataValue.aggMin), oldMapValue.aggMax.max(_newMapDataValue.aggMax))
              (key._1 -> result)
            } else (key._1 -> key._2)
          })

    }