Qual estrutura JSON usar para pares de valores-chave?


23

Qual formato JSON é a melhor escolha para pares de valores-chave e por quê?

[{"key1": "value1"}, {"key2": "value2"}]

Ou:

[{"Name": "key1", "Value": "value1"}, {"Name": "key2", "Value": "value2"}]

Ou:

{"key1": "value1", "key2": "value2"}

A primeira variante parece mais compacta e mais "semanticamente significativa". A segunda variante parece mais estruturada, o que pode ajudar a processá-la. A terceira variante parece ainda mais semântica.

Os pares de valores-chave serão usados ​​para anexar dados arbitrários a algum outro item. Os dados devem ser serializados como JSON para contorná-los através de um sistema.


3
A menos que você precise solicitar, por que não considerar {"key1": "value1", "key2": "value2"}?
Kennytm

4
JSON já é um dicionário (aninhado).
Kasey Speakman

1
Seu problema é que a descrição é ampla o suficiente para dizer que qualquer um desses formatos funcionará, e a verdadeira questão é como torná-lo mais simples de consumir, o que depende de quais tecnologias os clientes usam.
Script #

Você deve usar o mais simples que atenda às suas necessidades, espero que seja o formulário de objeto simples (nº 3). No entanto, se você estiver procurando por ainda mais opções, poderá usar duas matrizes em paralelo, uma para chaves e outra para valores; isso será o mais compacto possível, enquanto ainda houver suporte a chaves de objetos e chaves duplicadas (que não seriam suportadas no item 3).
Erik Eidt

Respostas:


10

A escolha da primeira ou da terceira opção depende do seu caso de uso. Se você estiver modelando muitas instâncias diferentes do mesmo tipo de coisa, escolha a primeira. Por exemplo, você tem uma lista de pessoas. Se você estiver modelando muitos atributos diferentes de uma coisa, escolha a terceira. Você pode ter teclas repetidas no primeiro formato, mas não no terceiro.

A segunda opção é terrível e ainda não encontrei um caso de uso apropriado. O motivo pelo qual é terrível, além de mais detalhado, é que, para o JSON de nível único, ele quebra a conversão automática da maioria das bibliotecas em um dicionário / mapa. Para JSON profundamente aninhado, ele quebra a interface de consulta semelhante ao XPath .

Isso torna difícil trabalhar com isso. E se você não souber suas chaves no momento da compilação, desejará uma interface de dicionário ou XPath, porque não poderá convertê-las em uma classe. Pode não parecer grande coisa agora, mas quanto mais tempo você tiver um formato de dados, mais difícil será mudar.


5
A grande vantagem da segunda opção é que ela funciona com chaves que não são de cadeia, em particular chaves compostas.
CodesInChaos

1
A segunda opção é terrível e você ainda precisa encontrar um caso de uso? A matriz de dicionários com muitos pares de chave / valor deve ter o formato mais comum para transmitir vários objetos.
precisa saber é o seguinte

2
@ gnasher729, no seu caso "a maioria formato comum" as verdadeiras chaves estão todos no lado da mão esquerda: [{"key1": "value1", "key2": "value2"}]. O segundo formato aqui é colocar a chave real no lado direito e usar outra chave chamada "Nome" para apontar para a chave real, tornando extremamente difícil analisar com ferramentas padrão.
Karl Bielefeldt

Vou te dar essa, @CodesInChaos. Mesmo lá, porém, teria que ser um caso muito especial. Eu nunca vi a necessidade disso na natureza.
Karl Bielefeldt

3
Desculpe, mas esta é uma resposta ruim. A segunda opção é muito comumente usada e aconselhada. Permite flexibilidade de chaves, extensão (com mais campos de valor / metadados) sem prejudicar os consumidores e pode preservar a ordem dos elementos. Além disso, os motivos apresentados são falsos: não quebra nenhuma "conversão automática" (apenas respeita a apresentação do autor como matriz) e funciona bem com uma interface de consulta semelhante ao XPath. A única desvantagem é o aumento da verbosidade.
Hejazzman

5

O terceiro formato é geralmente o melhor. No entanto, aqui está um exemplo de algo adequado para o 1º formato:

[{
  "username": "foo",
  "id": 1
}, {
  "username": "bar",
  "id": 2
}, {
  "username": "baz",
  "id": 3
}]

Aqui, cada objeto se refere a uma coisa separada (e cada objeto usa as mesmas chaves que as outras, para que não possam ser mescladas). No entanto, cada objeto da lista é armazenado { "username": "foo", "id": 1 }e não [{ "username": "foo" }, { "id": 1 }]porque 1) é mais curto e 2) está se referindo a uma coisa com um nome de usuário e um ID, não a uma coisa com um nome de usuário e outra com um ID.

O problema com a segunda opção é que ela se torna muito detalhada tanto como JSON quanto para trabalhar. No entanto, ele pode ser usado se você precisar armazenar meta-informações sobre a propriedade. Um exemplo:

{
  "key": "foo",
  "value": 1,
  "mutable": true
}

Aqui mutablese refere a um caso hipotético de se você pode modificar a propriedade em si, não o objeto pai. Meta-informações como essa são semelhantes às do JavaScript Object.defineProperty, que armazena informações "configuráveis", "enumeráveis" e "graváveis" sobre uma propriedade.


Eu estava tentando usar o primeiro formato para alguns JSON que estava enviando para um ponto de extremidade REST C # e não estava convertendo para um objeto de dicionário. Convertê-lo para o terceiro formato esclareceu isso.
fizch

5

Você diz que esses são pares chave / valor. Nesse caso, use # 3: dicionário de pares de chave / valor.

Se esses não são pares de chave / valor, não os chame de "chaves" e "valores" e use # 2, uma matriz de dicionários com conteúdo arbitrário.

A estrutura 1 é simplesmente estúpida, a menos que você precise de pares de chave / valor, mas também a ordem deles. O que você raramente faz.


3

Coloque-se no lugar da pessoa que recebe o json. Se eu não souber o nome da chave, como devo recuperá-lo com o primeiro ou o último formato? Você pode percorrer o json, é claro, mas como os três formatos atingem o mesmo resultado, é apenas uma questão de sintaxe. Penso que esta é a única pergunta significativa: se você souber os nomes das chaves, a primeira ou a última opção será mais compacta, se não a segunda opção será mais compreensível.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.