简体   繁体   中英

Convert a ruby nested hash in array of hashes

I'm trying to flat a nested hash. My hash has this structure:

    {
   "errorDescription":"",
   "message":"",
   "resultCode":"OK",
   "resultObj":{
      "categoryList":[
         {
            "asNew":"N",
            "categoryId":40000000,
            "categoryList":[
               {
                  "asNew":"N",
                  "categoryId":40000007,
                  "categoryList":[
                  ],
                  "categoryName":"CATALOGO",
                  "categoryType":"TYPE_NODE",
                  "contentId":40000007,
                  "contentTitle":"CATALOGO",
                  "contentType":"CATEGORY_NODE",
                  "orderId":0,
                  "urlPictures":""
               },
               {
                  "asNew":"N",
                  "categoryId":40000018,
                  "categoryList":[
                     {
                        "asNew":"N",
                        "categoryId":40000019,
                        "categoryList":[

                        ],
                        "categoryName":"CANALI CALCIO",
                        "categoryType":"TYPE_VOD",
                        "contentId":40000019,
                        "contentTitle":"CALCIO & SPORT",
                        "contentType":"CATEGORY_LEAF",
                        "orderId":0,
                        "urlPictures":""
                     },
                     {
                        "asNew":"N",
                        "categoryId":40000020,
                        "categoryList":[

                        ],
                        "categoryName":"CANALI CINEMA",
                        "categoryType":"TYPE_VOD",
                        "contentId":40000020,
                        "contentTitle":"CINEMA & SERIE",
                        "contentType":"CATEGORY_LEAF",
                        "orderId":1,
                        "urlPictures":""
                     }
                  ],
                  "categoryName":"CANALI TV",
                  "categoryType":"TYPE_NODE",
                  "contentId":40000018,
                  "contentTitle":"CANALI TV",
                  "contentType":"CATEGORY_NODE",
                  "orderId":1,
                  "urlPictures":""
               }
            ],
            "categoryName":"ROOT",
            "categoryType":"TYPE_NODE",
            "contentId":40000000,
            "contentTitle":"ROOT",
            "contentType":"",
            "orderId":0,
            "urlPictures":""
         }
      ]
   }
}

I must convert this hash in an array of objects, where every object has this structure:

                {
                  "asNew":"N",
                  "categoryId":40000007,
                  "categoryName":"CATALOGO",
                  "categoryType":"TYPE_NODE",
                  "contentId":40000007,
                  "contentTitle":"CATALOGO",
                  "contentType":"CATEGORY_NODE",
                  "orderId":0,
                  "urlPictures":""
               }

Basically every key "categoryList" has an array as value and this array has one or more hash with another key "categoryList". I must move all the objects in every categoryList array to another array without the categoryList 'key'.

edit

I add this method to Hash class

class Hash
  def find_all_values_for(key)
    result = []
    result << self[key]
    unless self.values.nil?
      self.values.each do |values|
        values = [values] unless values.is_a? Array
        values.each do |value|
          result += value.find_all_values_for(key) if value.is_a? Hash
        end
      end
    end
    result.flatten.compact
  end
end

And I map the resulting array deleting the CategoryList key

h.map { |c| c.except!('categoryList') }

It works but meybe there is a more efficient way.

This code will return the requested Array of objects.

def flatten_categoryList(categoryList)
  categoryList.inject([]) do |result, item|
    result + flatten_categoryList(item.delete("categoryList")) << item
  end
end

flatten_categoryList(h["resultObj"]["categoryList"])

I was unable to run yours to get a benchmark, so judging the solutions is currently subjective.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM