为什么JSON没有关联数组?

时间:2014-11-17 09:11:54

标签: arrays json yaml associative-array

为什么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做出的。

3 个答案:

答案 0 :(得分:5)

  

为什么JSON没有关联数组?

JSON没有PHP意义上的关联数组(例如,有序地图),但肯定有键/值映射。他们被称为“对象”。

  

我在技术层面上想知道为什么这个决定可能是针对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属性是一个对象。它的属性不是有序的,所以它不是有序的地图,而是一张地图。如果您需要其中的属性来订购,您必须向它们添加一个属性,指明订单是什么,然后在反序列化后应用该订单。

或者,您可以使用数组,然后在反序列化后构建地图:

{
    "productsBySku": [
        {
            "sku": "12J432",
            "price": 49.99,
            "qty_in_stock": 4
        },
        {
            "sku": "5X4352",
            "price": 29.99,
            "qty_in_stock": 5
        }
    ]
}

[1] 对于那些不知道的人,YAML代表“YAML不是标记语言。”

答案 1 :(得分:1)

JSON代表JavaScript Object Notation。正如它所说,它是一个像结构一样的javascript对象。 在JavaScript中,您没有associative arrays。但是你有object具有类似的结构。

与你的例子类似,你可以:

{
"productsBySku": {
    "12J432": {
        "price": 49.99,
        "qty_in_stock": 4
    },
    "5X4352": {
        "price": 29.99,
        "qty_in_stock": 5
    }
}

}

答案 2 :(得分:1)

因为JSON代表 JavaScript Object Notation 而JavaScript本身有对象可以使用类似关联数组,所以你会这样做(注意我必须修复属性名称中缺少quots以生成有效的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对象不能像关联数组一样使用,因为它们是   没有订购,对吗?我的意思是你不能通过一个对象做一个forEach   JavaScript中的属性,如果它被视为关联的   数组,你可以。我错了吗?

你的排序是对的,但是仍然可以使用forEach迭代对象属性:

// Object.keys will return an array of own object property names
Object.keys(obj).forEach(function(propertyName) {
   var propertyValue = obj[propertyName];
});

对象也可以像哈希或关联数组一样使用,但不能依赖于顺序。