¿Cómo representar un conjunto en JSON?

16

JSON admite las siguientes estructuras de datos (equivalentes de Java): escalar, matriz / lista y mapa.

A Setno es compatible de fábrica en JSON.

Pensé en varias formas de representar un conjunto en JSON:

[1] - Como una lista

Sin embargo, una lista tiene su propio pedido, por lo que las dos listas siguientes, ["a", "b"]y ["b", "a"]no son iguales como listas, sino que debe ser igual como conjuntos.

[2] - Como un mapa

Use el conjunto de claves del mapa e ignore los valores.

Pero nuevamente, usando la comparación estándar, los dos no son lo mismo que los mapas:

{"a": "foo", "b": "bar"}, {"a": null, "b": null}

[3] - Como un mapa, con un valor especial

Tome un escalar, diga 0o nully fuerce a que sea el valor de cada clave del mapa:

{"a": 0, "b": 0}

De esta manera, bajo las herramientas de comparación estándar, los objetos son iguales, incluso si se cambia el orden de las claves.

Sin embargo, esta técnica contamina el documento JSON con datos irrelevantes.

[4] - Como una lista ordenada

Volver a la primera sugerencia, pero esta vez como una lista ordenada. Este tipo de resuelve el problema de comparación.

Sin embargo, también debemos tener en cuenta la complejidad de la ordenación, y también que la notación de mapa maneja duplicados, mientras que una lista ordenada no lo hace. Ejemplo:

{"a": 400, "a": 9}se maneja como {"a": 9}, pero ["g", "g"]siempre lo sería ["g", "g"].

Habiendo dicho todo eso, me parece que la notación de la lista es más clara, pero la notación del mapa es más robusta para la duplicación de claves y hace que sea más difícil ser coherente con el valor especial (aunque nullparezca una buena opción para eso).

¿Qué piensas? ¿Cómo representaría un conjunto en JSON?

PD

Tenga en cuenta que la pregunta se trata simplemente de JSON. Sé que otros formatos, como yaml, están disponibles. Todavía...

Ron Klein
fuente
1
Los conjuntos no son compatibles con JSON, está fuera del alcance. Existe un conjunto, o una colección única y distinta, dentro del alcance de la aplicación. Debido a que es una colección, sería más obvio usar la sintaxis de la colección.
Zymus
1
¿Por qué querrías representar conjuntos en JSON? Recuerde que JSON es un formato de intercambio.
Andres F.
@AndresF. Pensé que sería una buena idea expresar el atributo de singularidad de los valores. No vincularía JSON solo al formato de intercambio. También puede ser útil para el almacenamiento de documentos (como en MongoDB).
Ron Klein
@RonKlein Bastante justo. Pero ugh ... no me hagas comenzar con MongoDB: P
Andres F.
En YAML, los conjuntos se representan como su opción [3], pero tiene una notación especial que JSON no tiene.
Jasmijn

Respuestas:

21

Pues no puedes. Como dijiste, puedes representar matrices y diccionarios. Tienes dos opciones.

Representa el conjunto como una matriz. Ventaja: la conversión de conjunto a conjunto y viceversa suele ser fácil. Desventaja: una matriz tiene un orden implícito, que un conjunto no tiene, por lo que la conversión de conjuntos idénticos en matrices JSON puede crear matrices que se considerarían diferentes. No hay forma de exigir que los elementos de la matriz sean únicos, por lo que una matriz JSON podría no contener un conjunto válido (obviamente, simplemente podría ignorar los duplicados; eso es lo que probablemente sucederá de todos modos).

Representa el conjunto como un diccionario, con un valor arbitrario por clave, por ejemplo 0 o nulo. Si simplemente ignora los valores, esta es una combinación perfecta. Por otro lado, es posible que no tenga soporte de biblioteca para extraer las claves de un diccionario como un conjunto, o para convertir un conjunto en un diccionario.

En mi entorno de programación, la conversión entre set y array es más fácil (el array a configurar perderá valores duplicados, que no deberían estar allí o se considerarían correctos), por lo que iría con los arrays. Pero eso es en gran medida una cuestión de opinión.

PERO: Hay un gran elefante gordo en la habitación que no se ha mencionado. Las claves en un diccionario JSON solo pueden ser cadenas. Si su conjunto no es un conjunto de cadenas, entonces solo tiene la opción de usar una matriz.

gnasher729
fuente
55
El caso límite de no cadenas es un buen argumento en contra de un diccionario.
Ron Klein
4

No intentes representar conjuntos en JSON. Hazlo cuando analices los datos.

Sus datos JSON deben tener un esquema que especifique qué campos deben tratarse como un conjunto, o puede tener metadatos incrustados en los propios datos JSON que describen cuándo una lista debe tratarse como un conjunto (por ejemplo {"houses": {"_type": "set", "value": [...]}}) o con una convención de nomenclatura.

Tenga en cuenta que según el estándar JSON, un objeto JSON puede tener claves duplicadas. Redacciones de ECMA-404:

Objetos

[...] La sintaxis JSON no impone ninguna restricción en las cadenas utilizadas como nombres, no requiere que las cadenas de nombres sean únicas y no asigna ninguna importancia al orden de los pares nombre / valor. Todas estas son consideraciones semánticas que pueden ser definidas por los procesadores JSON o en las especificaciones que definen los usos específicos de JSON para el intercambio de datos.

AFAICD, nada en la especificación prohíbe nombres no únicos, y hay muchas implementaciones de analizador JSON que pueden analizar nombres de objetos no únicos. RFC 7159 desalienta los nombres no únicos para la interoperabilidad, pero específicamente tampoco lo prohíbe, y continúa enumerando cómo se han visto varios analizadores que manejan nombres de objetos no únicos.

Y ECMA 404 tampoco requiere que se conserve el orden de la matriz:

Matrices

La sintaxis JSON no define ningún significado específico para el orden de los valores. Sin embargo, la estructura de matriz JSON a menudo se usa en situaciones donde hay alguna semántica en el pedido.

Esta redacción permite que las aplicaciones usen matrices para representar conjuntos si así lo eligen.

Lie Ryan
fuente