рекурсивно искать хеш в ruby ​​и возвращать массив элементов - PullRequest
1 голос
/ 02 февраля 2012

У меня есть хеш, который я получаю от использования JSON.parse. Я вставляю в БД в этот момент. Структура данных использует действия в виде дерева, поэтому я могу иметь такой хеш-код:

category_attributes
  name: "Gardening"
  items_attributes:
    item 1: "backhoe"
    item 2: "whellbarrel"
  children_attributes
    name: "seeds"
    items_attributes
      item 3: "various flower seeds"
      item 4: "various tree seeds"
    children_attributes
      name: "agricultural seeds"
      items_attributes
        item 5: "corn"
        item 6: "wheat"

Для этого хеша я бы хотел вернуть массив всех items_attributes. Я видел этот вопрос Рекурсивное прохождение хэша в Ruby , но он кажется другим. Есть ли способ рекурсивного поиска в хэше и возврата всех этих элементов? В идеале, пустые items_attributes должны возвращаться ни с чем, кроме nil.

ТНХ

Ответы [ 2 ]

3 голосов
/ 03 февраля 2012

Попробуйте это:

def extract_list(hash, collect = false)
  hash.map do |k, v|
    v.is_a?(Hash) ? extract_list(v, (k == "items_attributes")) : 
       (collect ? v : nil)
  end.compact.flatten
end

Теперь давайте проверим функцию:

>> input = {    
  'category_attributes' => {
    'name' => "Gardening",
    'items_attributes' => {
      'item 1' =>  "backhoe",
      'item 2' =>  "whellbarrel",
      'children_attributes' => {
        'name' =>  "seeds",
        'items_attributes' => {
          'item 3' =>  "various flower seeds",
          'item 4' =>  "various tree seeds"
        },      
        'children_attributes' => {
          'name' =>  "agricultural seeds",
          'items_attributes' => {
            'item 5' => "corn",
            'item 6' => "wheat"
          }
        }
      }
    }
  }
}

>> extract_list(input)    
=> ["various flower seeds", "various tree seeds", "wheat", "corn", 
     "backhoe", "whellbarrel"]
2 голосов
/ 02 февраля 2012

Вы можете сделать что-то вроде этого:

def collect_item_attributes h
  result = {}
  h.each do |k, v|
    if k == 'items_attributes'
      h[k].each {|k, v| result[k] = v } # <= tweak here    
    elsif v.is_a? Hash
      collect_item_attributes(h[k]).each do |k, v|
        result[k] = v
      end
    end
  end
  result
end

puts collect_item_attributes(h)
# => {"item 1"=>"backhoe", 
# "item 2"=>"whellbarrel", 
# "item 3"=>"various flower seeds", 
# "item 4"=>"various tree seeds", 
# "item 5"=>"corn", 
# "item 6"=>"wheat"}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...