Próbuję wygenerować trochę jsona za pomocą json4s biblioteka, która buduje jsona za pomocą dsl opartego na zagnieżdżonych strukturach krotek. Mam scala Seq
które chciałbym móc przekształcić w zagnieżdżanie krotek w ten sposób:
// scala Seq
val s = Seq("a", "b", "c", "d")
val rootItem = "id" -> 1234
// desired json
{
"a" : {
"b" : {
"c" : {
"d" : {
"id" : 1234
}
}
}
}
}
Jeśli zmusię go do zignorowania typów, mogę wytworzyć żądaną strukturę krotki w następujący sposób:
// yields ("a", ("b", ("c", ("d", ("id", 1234)))))
s.foldRight[Any](rootItem)(_ -> _)
ale ponieważ typ wyniku jest teraz oznaczony jako Any
ukryta konwersja, która zapisuje to jsonowinie odpalaj (i rzucaj wyjątek, gdy jest wywoływany jawnie), mimo że rzeczywisty typ jest poprawny. Nie mogę się dowiedzieć, jak skonstruować tę strukturę danych w bezpieczny sposób. Idealnie chciałbym rozwiązanie, które jest w stanie odpowiednio zbudować typ, chociaż rozumiem, że może to być niemożliwe, ponieważ wymaga informacji dostępnych tylko w czasie wykonywania (długość listy). Wiem, że scala obsługuje typy rekurencyjne, które wydaje się, że potencjalnie pasuje do ustawy, ale nie byłem w stanie zrozumieć, jak je w tym przypadku pracować i nie wiem, czy są bezpieczne dla „prawdziwego” systemu.
Odpowiedzi:
1 dla odpowiedzi № 1Nie będziesz w stanie tego zrobić zwykłym starym fałdem, ponieważ akumulator musi być tego samego typu przez cały czas.
Możesz przejść transformację do JSON w miarę upływu czasu:
val s = Seq("a", "b", "c", "d")
val rootItem = "id" -> 1234
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
val json = s.foldRight[JObject](rootItem)(_ -> _)
A potem możesz wykonać następujące czynności json
jest statycznie wpisany jako a JObject
:
scala> pretty(render(json))
res0: String =
{
"a" : {
"b" : {
"c" : {
"d" : {
"id" : 1234
}
}
}
}
}
(W przypisie jest sposób możesz zrobić krotnie z krotkami i skończyć z odpowiednim typem statycznym, ale to na pewno nie jest to, czego chcesz w tym przypadku.)