이벤트 배열이 포함 된 JSON 구조가 있습니다. 배열은 세 가지 이벤트 유형 A
, B
및 C
이 있다는 의미에서 "다형성"입니다 : 이 같은 객체 구조가없는JSON 읽기 [T] 읽기 : JsArray를 여러 개의 하위 집합으로 분할
{
...
"events": [
{ "eventType": "A", ...},
{ "eventType": "B", ...},
{ "eventType": "C", ...},
...
]
}
세 가지 이벤트 유형, 그래서에 대한 Reads
다른 필요 그들. 그리고 그 외에도에서, 전체 JSON 문서의 목표 케이스 클래스는 이벤트를 구별 :
case class Doc(
...,
aEvents: Seq[EventA],
bEvents: Seq[EventB],
cEvents: Seq[EventC],
...
)
json으로 배열 events
이 aEvents
에 매핑되는 세 개의 부분 집합으로 분할 될 수 있도록 내가 Reads[Doc]
의 내부를 정의 할 수있는 방법 , bEvents
및 cEvents
? 나는 (성공적인없이) 지금까지 시도 무엇
:
def eventReads(eventTypeName: String) = new Reads[JsArray] {
override def reads(json: JsValue): JsResult[JsArray] = json match {
case JsArray(seq) =>
val filtered = seq.filter { jsVal =>
(jsVal \ "eventType").asOpt[String].contains(eventTypeName)
}
JsSuccess(JsArray(filtered))
case _ => JsError("Must be an array")
}
}
:
먼저, 난 단지 특정 유형의 이벤트가 포함 된 다른 JsArray
원래 JsArray
변환하는 Reads[JsArray]
정의
다음과 같이 이것을 사용하면됩니다. Reads[Doc]
:
implicit val docReads: Reads[Doc] = (
...
(__ \ "events").read[JsArray](eventReads("A")).andThen... and
(__ \ "events").read[JsArray](eventReads("B")).andThen... and
(__ \ "events").read[JsArray](eventReads("C")).andThen... and
...
)(Doc.apply _)
그러나 여기에서 어떻게 진행해야할지 모르겠다. 나는 andThen
부분 (이벤트 A의 경우)의 모양은 가정
.andThen[Seq[EventA]](EventA.reads)
하지만이 API가 명시 적으로 대신 Reads[Seq[EventA]]
의 Reads[EventA]
를 전달하여 Seq[EventA]
를 만들 것으로 기대하기 때문에 그 작동하지 않습니다. 그리고 그 점을 제외하고는 결코 실행하지 못했기 때문에이 모든 접근법이 처음에는 합리적인지 확실하지 않습니다.
편집 : 경우에 원래 JsArray
알 수없는 이벤트 유형 (예를 들어, D
및 E
)를 포함은, 이러한 유형은 무시되어야하고 (대신 전체 Reads
실패 만드는) 최종 결과에서 탈락.
json 구조를 변경할 수 있습니까? 예 : '{ ..., 이벤트 : { a : [... A 이벤트 유형], b : [B 유형 이벤트 ...] c : [...의 이벤트 C] } } 이미 정의한 읽기를 사용하여 다시 변환하는 것이 더 쉬워야합니다. – marceloemanoel
다른 방법. JsArray를 Tuple3 [Seq [EventA]], Seq [EventB], Seq [EventC]로 변환하고 결과를 Doc에 매핑하십시오. –