0

I have the following JSON object:

{
  "name": "Womens",
  "position": 1,
  "url": "/collections/womens-all",
  "submenus": [
    {
      "name": "Apparel",
      "position": 1,
      "url": "/collections/womens-apparel-all",
      "submenus": [
        {
          "name": "Tees & Tanks",
          "position": 1,
          "url": "/collections/womens-tees",
          "submenus": []
        },
        {
          "name": "Silk & Tops",
          "position": 2,
          "url": "/collections/womens-tops",
          "submenus": []
        },
        {
          "name": "Sweaters & Sweatshirts",
          "position": 3,
          "url": "/collections/womens-sweaters",
          "submenus": []
        }
      ]
    },
    {
      "name": "Accessories",
      "position": 2,
      "url": "/collections/womens-all-accessories",
      "submenus": [
        {
          "name": "Petra",
          "position": 1,
          "url": "/collections/petra",
          "submenus": []
        },
        {
          "name": "Weekenders",
          "position": 2,
          "url": "/collections/womens-bags",
          "submenus": []
        },
        {
          "name": "Backpacks & Totes",
          "position": 3,
          "url": "/collections/womens-backpacks",
          "submenus": []
        },
        {
          "name": "Accessories & Shoes",
          "position": 4,
          "url": "/collections/womens-accessories",
          "submenus": []
        }
      ]
    }
  ]
}

I want to flatten this object's submenus into a single array containing every menu in the tree. The result would look like:

[
  {
    "name": "Apparel",
    "position": 1,
    "url": "/collections/womens-apparel-all",
    "submenus": []
  },
  {
    "name": "Accessories",
    "position": 2,
    "url": "/collections/womens-all-accessories",
    "submenus": []
  },
  {
    "name": "Petra",
    "position": 1,
    "url": "/collections/petra",
    "submenus": []
  },
  {
    "name": "Weekenders",
    "position": 2,
    "url": "/collections/womens-bags",
    "submenus": []
  },
  {
    "name": "Backpacks & Totes",
    "position": 3,
    "url": "/collections/womens-backpacks",
    "submenus": []
  },
  {
    "name": "Accessories & Shoes",
    "position": 4,
    "url": "/collections/womens-accessories",
    "submenus": []
  },
  {
    "name": "Tees & Tanks",
    "position": 1,
    "url": "/collections/womens-tees",
    "submenus": []
  },
  {
    "name": "Silk & Tops",
    "position": 2,
    "url": "/collections/womens-tops",
    "submenus": []
  },
  {
    "name": "Sweaters & Sweatshirts",
    "position": 3,
    "url": "/collections/womens-sweaters",
    "submenus": []
  }
]

I feel like a recursive solution would be best, but I can't get it right. What would be the best approach for this problem?

  • @Leron The only problem with that approach is that it doesn't account of an arbitrary level of nested submenus. That code will only extract up to the second layer, if I'm thinking correctly. – Taylor Lapeyre Mar 14 '14 at 17:52
  • Yeah, you are correct. Sorry, for misleading you. – Leron Mar 14 '14 at 17:54

1 Answers1

1

This should do, assuming you forgot "Womens" in the resulting array in your example:

def flatten(dct, res=None):
    if res is None:
        res = []
    subdct = {}
    for k in dct:
        v = dct[k]
        if k == "submenus":
            for e in v:
                flatten(e, res)
            v = []
        subdct[k] = v
    res.append(subdct)
    return res

to be called like

result = flatten(json_object)
uselpa
  • 18,732
  • 2
  • 34
  • 52