12

I have the following JSON structure but am wondering if there would be any way to simplify it further. Can 'ingredient' and 'quantity' be removed from all the entries somehow to help reduce it?

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"
                        }
                    ]
                }
            ]
        };
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Phil
  • 1,610
  • 4
  • 26
  • 40
  • 3
    You shouldn't be worried about reducing it unless the data is not transferring fast enough, right now you should be more worried that the data structure displays the correct intent – aaronman Jul 28 '13 at 22:23

3 Answers3

17

Yes, you can simplify that quite a bit:

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

An explanation:

  • The top level of your example is a single-item object: {"recipes": <...>}. Unless this is a simplified version of an object that will actually have other items in it, that's redundant. Your code knows what it's sending/recieving, so there's no extra information there.

  • The value of your {"recipes": <...>} object is an array of two-item objects, with the keys "name" and "ingredients". Whenever you have an array like this, it makes more sense (and is more compact) to replace it with an object. As a rule of thumb:

    If the keys in an array of objects can be replaced by "key" and "value" and still make sense, replace the array with a single {"key_name": <value>, ...} object.

  • The same rule applies to your [{"ingredient": <...>, "quantity": <...>}, ...] array: each object can be replaced by a key-value pair and continue to make sense.

The end result is that this representation of the information is 87 characters in length (with extraneous whitespace removed), compared to your original's 249 characters - a 65% reduction.

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
2

Definitely. One way would be :

var cooking = {
        "recipes" : [
            {
                "name":"pizza",
                "ingredients" : [
                    "cheese", 
                     "tomato"
                    ],
                   "quantities" : [ // Have to be in order of ingredients
                        "100g",
                        "200g"
                ]
            }
        ]
  }

Or

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

Since they are all pizzas you can remove the name.

var cooking = {
    "recipes" : [
        {
            "ingredients" : [
                "cheese:100g", 
                 "tomato:200g"
                ]
        },
        {
            "ingredients" : [
                "ham:100g", 
                 "pineapple:200g"
                ]
        }
    ]
}
fastcodejava
  • 39,895
  • 28
  • 133
  • 186
  • 4
    I'm not sure relying on the ordering in the arrays is the best way to associate ingredients and quantities. – brianestey Jul 29 '13 at 03:26
  • @brianestey It may not be the best solution but OP wanted a different solution which is less verbose. The first solution uses "cheese", "tomato" etc as names which would really be on the value side. – fastcodejava Jul 29 '13 at 04:33
  • Care to explain why `"cheese"` and `"tomato"` shouldn't be keys in this case? They're obviously not going to occur twice in the same recipe, and are equally obviously always going to be strings. – Zero Piraeus Jul 29 '13 at 05:24
  • 2
    Your two solutions are both quite poorly designed: the first relies on an implicit parallel relationship between elements of two different arrays, which is both unsemantic and fragile, and the second invents a domain-specific language specifically in order to simulate an object using an array, which is pointless, and will complicate any code that has to create or parse the message. – Zero Piraeus Jul 29 '13 at 05:24
  • Also, [neither of them are valid JSON](http://stackoverflow.com/a/4183018/1014938). – Zero Piraeus Jul 29 '13 at 05:26
  • @ZeroPiraeus That all valid JSON without the comment. The comment is put for clarity. – fastcodejava Jul 29 '13 at 23:13
  • 1
    @fastcodejava It's not JSON, it's [a JavaScript object inside an assignment](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/); – Ruan Mendes Oct 12 '15 at 16:52
0

Hope this simplifies it for you ! Json must be written in a way so that its minimal and comprehensible for both computers and humans.

var cooking = {
            "recipes" :
            [           
            {
                "name":"pizza",
                "cheese": "100g"
                "tomato": "200g"
            }           
            ,
            {
                "name":"pizza 2",
                "ham": "300g"
                "pineapple": "300g"
            }
            ]
            }
    };
Uzair
  • 1,529
  • 14
  • 17