JSON obsługuje następujące struktury danych (odpowiedniki Java): Skalarne, Tablica / Lista i Mapa.
A Set
nie jest obsługiwany po wyjęciu z pudełka w JSON.
Pomyślałem o kilku sposobach przedstawienia zestawu w JSON:
[1] - Jako lista
Jednak lista ma własną kolejność, więc następujących dwóch list, ["a", "b"]
a ["b", "a"]
nie są równe jak list, ale powinny one być równe jak zestawy.
[2] - Jako mapa
Użyj zestawu kluczy mapy i zignoruj wartości.
Ale znowu, używając standardowego porównania, te dwa nie są takie same jak mapy:
{"a": "foo", "b": "bar"}
, {"a": null, "b": null}
[3] - Jako mapa o specjalnej wartości
Weź skalar, powiedz 0
lub null
i zmuś, aby był wartością każdego klucza na mapie:
{"a": 0, "b": 0}
W ten sposób, zgodnie ze standardowymi narzędziami porównywania, obiekty są równe, nawet po zmianie kolejności kluczy.
Jednak ta technika zanieczyszcza dokument JSON nieistotnymi danymi.
[4] - Jako lista uporządkowana
Wróć do pierwszej sugestii, ale tym razem jako uporządkowanej listy. Ten rodzaj rozwiązuje problem porównania.
Należy jednak pamiętać o złożoności sortowania, a także, że notacja mapy obsługuje duplikaty, podczas gdy sortowana lista nie. Przykład:
{"a": 400, "a": 9}
jest traktowane jako {"a": 9}
, ale ["g", "g"]
zawsze tak będzie ["g", "g"]
.
Powiedziawszy to wszystko, wydaje mi się, że notacja na liście jest wyraźniejsza, ale notacja mapy jest bardziej odporna na powielanie kluczy i utrudnia spójność w odniesieniu do specjalnej wartości (chociaż null
wydaje się to dobrym wyborem).
Co myślisz? Jak reprezentowałbyś zestaw w JSON?
PS
Zauważ, że pytanie dotyczy wyłącznie JSON. Wiem, że inne formaty, takie jak yaml, są dostępne. Nadal...
źródło
Odpowiedzi:
Nie możesz. Jak powiedziałeś, możesz reprezentować tablice i słowniki. Masz dwie możliwości.
Reprezentuj zestaw jako tablicę. Zaleta: Konwersja z zestawu na tablicę iz powrotem jest zwykle łatwa. Wada: tablica ma domyślną kolejność, której nie ma, więc konwersja identycznych zestawów na tablice JSON może tworzyć tablice, które można by uznać za różne. Nie ma sposobu, aby wymusić, że elementy tablicy są unikalne, więc tablica JSON może nie zawierać prawidłowego zestawu (oczywiście możesz po prostu zignorować duplikaty; i tak może się zdarzyć).
Reprezentuj zestaw jako słownik, z dowolną wartością na klucz, na przykład 0 lub null. Jeśli po prostu zignorujesz wartości, będzie to idealne dopasowanie. Z drugiej strony możesz nie mieć obsługi biblioteki w celu wyodrębnienia kluczy słownika jako zestawu lub przekształcenia zestawu w słownik.
W moim środowisku programistycznym konwersja między zestawem a tablicą jest łatwiejsza (tablica do zestawu straci zduplikowane wartości, których albo nie powinno tam być, albo byłoby uważane za prawidłowe), dlatego z tego powodu wybrałbym tablice. Ale to w dużej mierze kwestia opinii.
ALE: W pokoju jest wielki gruby słoń, o którym nie wspomniano. Klucze w słowniku JSON mogą być tylko ciągami znaków. Jeśli twój zestaw nie jest zbiorem ciągów, możesz jedynie użyć tablicy.
źródło
Nie próbuj reprezentować zbiorów w JSON. Zrób to podczas analizowania danych.
Twoje dane JSON powinny mieć schemat, który określa, które pola powinny być traktowane jako zestaw, lub możesz mieć metadane osadzone w samych danych JSON, które opisują, kiedy lista powinna być traktowana jako zestaw (np.
{"houses": {"_type": "set", "value": [...]}}
) Lub z konwencją nazewnictwa.Należy pamiętać, że zgodnie ze standardem JSON obiekt JSON może mieć zduplikowane klucze. Treść ECMA-404:
AFAICD, nic w specyfikacji nie zabrania unikatowych nazw, a istnieje wiele implementacji parsera JSON, które mogą analizować nie unikalne nazwy obiektów. RFC 7159 odradza niejednoznaczne nazwy dla interoperacyjności, ale konkretnie też nie zabrania jej, i przechodzi do wykazania, w jaki sposób różne parsery były postrzegane do obsługi nie unikalnych nazw obiektów.
ECMA 404 również nie wymaga zachowania kolejności tablic:
To sformułowanie pozwala aplikacjom używać tablic do reprezentowania zbiorów, jeśli tak wybiorą.
źródło