Scala объединяет массивы и снижает ценность - PullRequest
0 голосов
/ 28 апреля 2018

У меня есть два массива пар ключей / значений [[String, Int)], к которым я хочу присоединиться, но я возвращаю минимальное значение только при совпадении ключа.

val a = Array(("personA", 1), ("personB", 4), ("personC", 5))
val b = Array(("personC", 4), ("personA", 2))

Цель: c = Array((personA, 1), (personC, 4))

val c = a.join(b).collect()

Результат: c = Array((personA, (1, 2)), (personC, (5, 4)))

Я пытался добиться этого с помощью метода объединения, но у меня возникают трудности с уменьшением значений после их объединения в один массив: Array[(String, (Int, Int))].

1 Ответ

0 голосов
/ 28 апреля 2018

Попробуйте это:

val a = Array(("personA", 1), ("personB", 4), ("personC", 5))
val b = Array(("personC", 4), ("personA", 2))
val bMap = b.toMap
val cMap = a.toMap.filterKeys(bMap.contains).map {
  case(k, v) => k -> Math.min(v, bMap(k))
}
val c = cMap.toArray

Метод toMap преобразует Array[(String, Int)] в Map[String, Int]; filterKeys затем используется для сохранения только ключей (строк) в a.toMap, которые также находятся в b.toMap. Затем операция map выбирает минимальное значение из двух доступных значений для каждого ключа и создает новую карту, связывающую каждый ключ с этим минимальным значением. Наконец, мы конвертируем полученную карту обратно в Array[(String, Int)], используя toArray.

ОБНОВЛЕНО

Кстати: я не уверен, откуда у вас метод Array.join: у Array такого метода нет, поэтому a.join(b) у меня не работает. Однако я подозреваю, что a и b могут быть коллекциями Apache Spark PairRDD (или чем-то подобным). Если это так, то вы можете объединить a и b, а затем сопоставить значения с минимумом каждой пары (операция reduce - это не то, что вам нужно) следующим образом:

a.join(b).mapValues(v => Math.min(v._1, v._2)).collect

collect преобразует результат в Array[(String, Int)], как вам требуется.

...