Jak reprezentować zestaw w JSON?

16

JSON obsługuje następujące struktury danych (odpowiedniki Java): Skalarne, Tablica / Lista i Mapa.

A Setnie 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 0lub nulli 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ż nullwydaje 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...

Ron Klein
źródło
1
Zestawy nie są obsługiwane przez JSON, jest to poza zakresem. Zestaw lub odrębna, unikalna kolekcja istnieje w zakresie aplikacji. Ponieważ jest to kolekcja, bardziej oczywiste byłoby użycie składni kolekcji.
Zymus,
1
Dlaczego chcesz reprezentować zestawy w JSON? Pamiętaj, JSON jest formatem wymiany.
Andres F.,
@AndresF. Pomyślałem, że dobrym pomysłem byłoby wyrażenie atrybutu wyjątkowości wartości. Nie wiązałbym JSON-a tylko z formatem wymiany. Może być również przydatny do przechowywania dokumentów (jak w MongoDB).
Ron Klein,
@RonKlein Do przyjęcia. Ale ugh ... nie zaczynaj od MongoDB: P
Andres F.
W YAML zestawy są reprezentowane jako twoja opcja [3], ale ma specjalną notację, której JSON nie ma.
Jasmijn

Odpowiedzi:

21

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.

gnasher729
źródło
5
przypadek krawędzi nie-ciągów jest dobrym argumentem przeciwko słownikowi.
Ron Klein,
4

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:

Obiekty

[...] Składnia JSON nie nakłada żadnych ograniczeń na ciągi znaków używane jako nazwy, nie wymaga, aby ciągi nazw były unikalne i nie przypisywał żadnego znaczenia porządkowaniu par nazwa / wartość. Są to wszystkie kwestie semantyczne, które mogą być zdefiniowane przez procesory JSON lub w specyfikacjach definiujących konkretne zastosowania JSON do wymiany danych.

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:

Tablice

Składnia JSON nie definiuje żadnego konkretnego znaczenia dla uporządkowania wartości. Jednak struktura tablic JSON jest często używana w sytuacjach, w których porządkowanie ma pewną semantykę.

To sformułowanie pozwala aplikacjom używać tablic do reprezentowania zbiorów, jeśli tak wybiorą.

Lie Ryan
źródło