简化JSON结构

12

我有以下的JSON结构,但不知道是否有简化它的方法。是否可以从所有条目中删除“ingredient”和“quantity”以帮助进一步缩减它?

var cooking = {
            "recipes" : [
                {
                    "name":"pizza",
                    "ingredients" : [
                        {
                            "ingredient" : "cheese",
                            "quantity" : "100g"
                        },
                        {
                            "ingredient" : "tomato",
                            "quantity" : "200g"
                        }
                    ]
                },
                {
                    "name":"pizza 2",
                    "ingredients" : [
                        {
                            "ingredient" : "ham",
                            "quantity" : "300g"
                        },
                        {
                            "ingredient" : "pineapple",
                            "quantity" : "300g"
                        }
                    ]
                }
            ]
        };

3
除非数据传输不够快,否则您无需担心减少数据量,现在您应更关注确保数据结构正确显示意图。 - aaronman
3个回答

17

是的,你可以将其简化很多:

var recipes = {
    "pizza": {
        "cheese": "100g",
        "tomato": "200g"
    },
    "pizza 2": {
        "ham": "300g",
        "pineapple": "300g"
    }
}

解释:

  • 你的示例的顶层是一个包含单个项的对象:{"recipes": <...>}。除非这是一个实际上会有其他项的对象的简化版本,否则这是多余的。你的代码知道它正在发送/接收什么,因此没有额外的信息。

  • 你的 {"recipes": <...>} 对象的值是一个包含两个项的对象数组,其中键为 "name""ingredients"。每当你有像这样的数组时,用一个对象替换它更有意义(且更紧凑)。作为经验法则:

    如果对象数组中的键可以被替换为 "key""value" 并且仍然有意义,请使用单个 {"key_name": <value>, ...} 对象替换数组。

  • 同样的规则也适用于你的 [{"ingredient": <...>, "quantity": <...>}, ...] 数组:每个对象可以被替换为键值对,并继续保持有意义。

最终结果是,这个信息表示方式长度为87个字符(去除额外的空格),而你原来的方式长度为249个字符——缩减了65%。


有点困惑于这个踩的行为...如果这个表述有问题,我并没有看出来。 - Zero Piraeus
没有点踩,但我认为是因为你去掉了“食谱”部分。 - aaronman
@aaronman 嗯,也许吧。不过在 OP 的例子中完全是多余的。 - Zero Piraeus
1
问题实际上不应该出现在SO上,这是不必要的,显然也不是创建对象的最佳方式。 - aaronman

2
当然可以。一种方法是:
var cooking = {
        "recipes" : [
            {
                "name":"pizza",
                "ingredients" : [
                    "cheese", 
                     "tomato"
                    ],
                   "quantities" : [ // Have to be in order of ingredients
                        "100g",
                        "200g"
                ]
            }
        ]
  }

或者
var cooking = {
    "recipes" : [
        {
            "name":"pizza",
            "ingredients" : [ // Putting ingredient and quantity together
                "cheese:100g", 
                 "tomato:200g"
                ]
        }
    ]
}

由于它们都是披萨,你可以去掉名称。

var cooking = {
    "recipes" : [
        {
            "ingredients" : [
                "cheese:100g", 
                 "tomato:200g"
                ]
        },
        {
            "ingredients" : [
                "ham:100g", 
                 "pineapple:200g"
                ]
        }
    ]
}

4
我不确定依赖数组中的顺序来关联配料和数量是否是最好的方式。 - brianestey
@brianestey 这可能不是最好的解决方案,但 OP 想要一个不那么冗长的不同解决方案。第一个解决方案使用“cheese”、“tomato”等名称作为值的一部分。 - fastcodejava
能否解释一下为什么在这种情况下“cheese”和“tomato”不应该是键?显然它们不会在同一份食谱中出现两次,而且显然它们始终都是字符串。 - Zero Piraeus
2
你的两个解决方案都设计得相当糟糕:第一个依赖于两个不同数组元素之间的隐式并行关系,这既不符合语义也很脆弱;第二个则是发明了一种特定领域语言,专门用于使用数组模拟对象,这是毫无意义的,并且会使任何需要创建或解析消息的代码变得更加复杂。 - Zero Piraeus
1
@fastcodejava 这不是JSON,而是一个赋值语句中的JavaScript对象 - Ruan Mendes
显示剩余2条评论

0
希望这能让你更简单明了!JSON必须以一种既对计算机又对人类易于理解的方式编写。
var cooking = {
            "recipes" :
            [           
            {
                "name":"pizza",
                "cheese": "100g"
                "tomato": "200g"
            }           
            ,
            {
                "name":"pizza 2",
                "ham": "300g"
                "pineapple": "300g"
            }
            ]
            }
    };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接