Объединить несколько массивов json в circe

Допустим, у нас есть 2 массива json. Как объединить их в один массив с помощью circe? Пример:

Массив 1:

[{"id": 1}, {"id": 2}, {"id": 3}]

Массив 2:

[{"id": 4}, {"id": 5}, {"id": 6}]

Нужный:

[{"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}]

Я пробовал deepMerge, но он сохраняет только содержимое аргумента, а не вызывающего объекта.


person Haspemulator    schedule 14.04.2016    source источник


Ответы (1)


Предположим, у нас есть следующая настройка (для удобства я использую circe-literal, но ваши значения Json могут быть откуда угодно):

import io.circe.Json, io.circe.literal._

val a1: Json = json"""[{"id": 1}, {"id": 2}, {"id": 3}]"""
val a2: Json = json"""[{"id": 4}, {"id": 5}, {"id": 6}]"""

Теперь мы можем объединить их следующим образом:

for { a1s <- a1.asArray; a2s <- a2.asArray } yield Json.fromValues(a1s ++ a2s)

Or:

import cats.std.option._, cats.syntax.cartesian._

(a1.asArray |@| a2.asArray).map(_ ++ _).map(Json.fromValues)

Оба этих подхода дадут вам Option[Json], который будет None, если a1 или a2 не представляют массивы JSON. Вам решать, что вы хотите, чтобы произошло в этой ситуации, например, .getOrElse(a2) или .getOrElse(a1.deepMerge(a2)) могут быть разумными вариантами.

Кстати, в текущем контракте deepMerge говорится следующее:

Null, Array, Boolean, String и Number обрабатываются как значения, а значения из аргумента JSON полностью заменяют значения из этого JSON.

Однако это не высечено на камне, и может быть разумным иметь deepMerge объединение массивов JSON — если вы хотите открыть проблему, мы можем еще немного подумать об этом.

person Travis Brown    schedule 14.04.2016