为啥 JSON 没有关联数组?
Posted
技术标签:
【中文标题】为啥 JSON 没有关联数组?【英文标题】:Why doesn't JSON have associative arrays?为什么 JSON 没有关联数组? 【发布时间】:2015-01-14 03:42:00 【问题描述】:为什么 JSON 没有关联数组? YAML 可以。
你不能在 JSON 中这样做:
productsBySku: [
12J432:
price: 49.99,
qty_in_stock: 4
,
5X4352:
price: 29.99,
qty_in_stock: 5
]
但是在 YAML 中你可以这样做:
productsBySku:
- 12J432:
price: 49.99,
qty_in_stock: 4
- 5X4352:
price: 29.99,
qty_in_stock: 5
从技术层面上来说,我想知道为什么会为 JSON 做出这个决定。
【问题讨论】:
JSON 有“关联数组”,它们被称为“对象”。您的 YAML 示例实际上是一个包含两个对象的数组,因此在 JSON 中它将是:"productsBySku": [ "12J432": ... , "5X4352": ... ]
为什么不呢?因为 JSON 在设计上是 javascript 的一个子集。而且 JavaScript 没有关联数组,无论其他人声称什么(对象属性没有排序)。
谢谢。如果这个问题不适合 SO,我很抱歉。老实说,我只是想了解事情背后的原因。
【参考方案1】:
因为 JSON 代表 JavaScript Object Notation 而 JavaScript 本身 具有对象 可以像 关联数组一样工作,所以您可以这样做(注意我必须修复属性名称中缺少引号的问题才能生成有效的 JSON 样本):
"productsBySku":
"12J432":
"price": 49.99,
"qty_in_stock": 4
,
"5X4352":
"price": 29.99,
"qty_in_stock": 5
...您可以使用for..in
迭代对象属性:
for(var property in obj.propductsBySku)
// You don't want properties from the prototype
if(obj.productsBySku.hasOwnProperty(property))
var propertyValue = obj.productsBySku[property];
您还可以使用Object.keys(obj.productsBySku)
获取所有密钥。
OP 说...
但是 JSON 对象不能像关联数组一样使用,因为它们是 没订对吧?我的意思是你不能通过一个对象的 JavaScript 中的属性,如果它被视为关联 数组,你可以。我错了吗?
您说得对,但对象属性仍然可以使用 forEach
进行迭代:
// Object.keys will return an array of own object property names
Object.keys(obj).forEach(function(propertyName)
var propertyValue = obj[propertyName];
);
对象也可以像散列或关联数组一样使用,但不能依赖顺序。
【讨论】:
但是 JSON 对象不能像关联数组一样使用,因为它们没有排序,对吧?我的意思是你不能通过 JavaScript 中对象的属性来执行 forEach,如果它被视为关联数组,你可以。我错了吗? @CommaToast 我更新了我的答案,向您展示如何使用forEach
。
好的,我接受 forEach 可以这样使用。我仍然不知道为什么你不能有一个有序的地图,因为我希望能够有一个我可以在地图键或订单上使用点语法的地方。猜猜你不可能拥有一切。【参考方案2】:
为什么 JSON 没有关联数组?
JSON 没有 php 意义上的关联数组(例如,ordered 映射),但它肯定有键/值映射。它们被称为“对象”。
我在技术层面上想知道为什么会为 JSON 做出这个决定。
Crockford 将 JSON 设计为 JavaScript 对象初始化语法的子集。 JavaScript 没有关联数组(在有序映射的意义上),这毕竟是非常不寻常的,所以 JSON 没有。
YAML 可以
是吗? I'm not seeing them 和 Biffen seems to suggest otherwise。
阅读 YAML 规范,您的 YAML 完全等同于这个 JSON(一个对象数组,每个对象都有一个指向从属对象的键):
"productsBySku": [
"12J432":
"price": 49.99,
"qty_in_stock": 4
,
"5X4352":
"price": 29.99,
"qty_in_stock": 5
]
即使 YAML 确实有它们,YAML 也不是 JSON[1]。 ;-) 它们是不同的数据符号,具有不同的设计目标。 XML 有名称空间,而 JSON 也没有。 YAML 支持通过引用重用节点,这允许循环结构,而 JSON 不支持。
你不能在 JSON 中这样做
这取决于你想要做什么。同样,据我所知,您的 YAML 与上面的 JSON 完全相同。
如果您的目标是按 SKU 列出该产品列表,您可以:
"productsBySku":
"12J432":
"price": 49.99,
"qty_in_stock": 4
,
"5X4352":
"price": 29.99,
"qty_in_stock": 5
productsBySku
属性是一个对象。它的属性不是ordered,所以它不是一个有序的map,而是一个map。如果您需要其中的属性具有顺序,则必须向它们添加一个属性,指示顺序是什么,然后在反序列化后应用该顺序。
或者,您可以使用数组,然后在反序列化后构建您的地图:
"productsBySku": [
"sku": "12J432",
"price": 49.99,
"qty_in_stock": 4
,
"sku": "5X4352",
"price": 29.99,
"qty_in_stock": 5
]
[1]对于那些不知道的人,YAML 代表“YAML Ain't Markup Language”。
【讨论】:
【参考方案3】:JSON 代表 JavaScript 对象表示法。正如它所说,它是一个类似结构的javascript对象。
在 JavaScript 中你没有associative arrays
。但是你有 object
有类似的结构。
与您的示例非常相似,您可以:
"productsBySku":
"12J432":
"price": 49.99,
"qty_in_stock": 4
,
"5X4352":
"price": 29.99,
"qty_in_stock": 5
【讨论】:
以上是关于为啥 JSON 没有关联数组?的主要内容,如果未能解决你的问题,请参考以下文章