键值对使用哪种JSON结构?


23

对于键值对,哪种JSON格式是更好的选择,为什么?

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

要么:

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

要么:

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

第一个变体看起来更紧凑,更“有意义”。第二个变体看起来结构更均匀,可能有助于处理它。第三个变体似乎更具语义。

键值对将用于将任意数据附加到其他项目。数据必须序列化为JSON才能在系统中四舍五入。


3
除非您需要订购,否则为什么不考虑{"key1": "value1", "key2": "value2"}
kennytm

4
JSON已经是一个(嵌套)字典。
Kasey Speakman

1
您的问题是描述足够广泛,以至于这些格式中的任何一种都可以使用,而真正的问题是如何使其更易于使用,这取决于客户使用什么技术。
scriptin

您应该使用满足您需求的最简单的方法,希望它将成为简单的对象形式(#3)。但是,如果您正在寻找更多选项,则可以并行使用两个数组,一个用于键,一个用于值;它将尽可能紧凑,同时仍支持对象键和重复键(#3则不支持)。
Erik Eidt

Answers:


10

选择第一个还是第三个选项取决于您的用例。如果要为同一类型的事物建模许多不同的实例,请选择第一个。例如,您有一个人员列表。如果要为一件事建模许多不同的属性,请选择第三个。您可以使用第一种格式重复键,但不能使用第三种格式。

第二种选择很糟糕,我还没有找到合适的用例。除了更冗长之外,其可怕的原因还在于,对于单级JSON,它破坏了大多数库自动转换为字典/地图的功能。对于深度嵌套的JSON,它破坏了类似XPath的查询接口。

这使工作变得很痛苦。而且,如果您在编译时不知道键,您将需要字典或XPath接口,因为您将无法将其转换为类。现在看来似乎没什么大不了的,但是数据格式越长,更改的难度就越大。


5
第二个选项的最大优点是它可以与非字符串键(特别是复合键)一起使用。
CodesInChaos

1
第二个选择很糟糕,您还没有找到用例吗?具有许多键/值对的字典数组必须是用于传输多个对象的最常用格式。
gnasher729

2
@ gnasher729,在您的“最常用格式”情况下,实际键都在左侧: [{"key1": "value1", "key2": "value2"}]。这里的第二种格式是将实键放在右侧,并使用另一个称为“名称”的键将您指向实键,这使得使用标准工具进行解析非常困难。
Karl Bielefeldt

我给你一个,@ CodesInChaos。即使到那里,也必须是一个非常特殊的情况。我从来没有见过在野外需要它。
Karl Bielefeldt

3
对不起,但这是一个错误的答案。第二个选项是非常常用和建议的。它允许键灵活,允许扩展(具有更多的value / metadata字段)而不会破坏使用者,并且可以保留元素顺序。另外,给出的原因是虚假的:它不会破坏任何“自动转换”(它仅尊重作者作为数组的表示形式),并且可以与类似XPath的查询接口一起正常工作。唯一的缺点是冗长程度增加。
Hejazzman,

5

第三格式是一般最好的。但是,以下是适合第一种格式的示例:

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

在这里,每个对象指的是一个单独的事物(每个对象使用与其他对象相同的键,因此无法合并)。但是,列表中的每个对象的存储方式{ "username": "foo", "id": 1 }不是[{ "username": "foo" }, { "id": 1 }]因为1)它更短,2)它是指具有用户名和ID的一件事,而不是具有用户名和ID的一件事。

第二个选项的问题是,无论是作为JSON还是要使用它,它都变得非常冗长。但是,如果您需要存储有关该属性的元信息,则可以使用它。一个例子:

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

这里mutable是指是否可以修改属性本身(而不是父对象)的一种假设情况。这样的元信息类似于JavaScript的元信息,JavaScript Object.defineProperty存储有关属性的“可配置”,“可枚举”和“可写”信息。


我正在尝试将第一种格式用于发送到C#REST端点的某些JSON,但未转换为字典对象。将其转换为第三种格式可以清除该问题。
fizch

5

您说这些是键/值对。在这种情况下,请使用#3:键/值对字典。

如果这些不是键/值对,则不要将它们称为“键”和“值”,而应使用#2,即具有任意内容的字典数组。

除非您需要键/值对以及它们的顺序,否则结构1只是愚蠢的。你很少这样做。


3

将您自己放在接受json的人的鞋子上。如果我不知道键名,我应该如何以第一种或最后一种格式来检索它?您当然可以遍历json,但是由于所有三种格式都达到相同的结果,因此这只是语法问题。我认为这是唯一有意义的问题:如果您知道键名,则第一个或最后一个选项会更紧凑,如果不是,则第二个选项更容易理解。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.