2016-06-28 2 views
0

У меня есть глубоко вложенный хэш Ruby, который мне нужно преобразовать в другой хэш. Хеш может иметь 0 или более детей. Вот входной хэш:Преобразование глубоко вложенного рубинового хэша

"{'id' => 'apple', 'children' => [{'id' => 'ipad', 'children' => [{'id' => 'ipadmini'}]},{'id' => 'ipadmini'}]}" 

выход

[{"ipad"=>{"id"=>"ipad", "paths"=>[[{"id"=>"apple"}, {"id"=>"ipad"}]]}}, 
{"ipadmini"=>{"id"=>"ipadmini", "paths"=>[[{"id"=>"ipad"}, {"id"=>"ipadmini"}], [{"id"=>"apple"}, {"id"=>"ipad"}, {"id"=>"ipadmini"}]]}}, {"apple"=>{"id"=>"apple", "paths"=>[[{"id"=>"apple"}]]}}] 

мой код:

def construct_concept(concept) 
    h = {} 
    c = Hash[*concept.to_a.first] 
    c['paths'] = [[Hash[*concept.to_a.first]]] 
    h[concept['id']] = c 
    h 
end 

def parent_child_concepts(concepts) 
    pc = {} 
    pc[:parent] = Hash[*concepts.first] 
    pc[:children] = concepts.values_at('children').flatten.map {|child| parent_child_concepts(child)} || [] 
    pc 
end 

def add_parent_child_paths(parent_hash,children_array) 
    h = {} 
    parent_hash.each do |parent_key,parent_value| 
     h[parent_key] = parent_value 
     children_array.each do |child| 
      child.each do |k,v| 
       h[k] = v 
       h[k]['paths'].map {|path| path.unshift({'id' => parent_key})} 
      end 
     end 
    end 
    h 
end 

def build_concept_data(concepts) 
    #concept {"id"=>"apple", "children"=>[{"id"=>"ipad"}]} 
    parsed_concepts = parent_child_concepts(concepts) 
    parent = construct_concept(parsed_concepts[:parent]) 
    children = parsed_concepts[:children].each_with_object([]) {|child,accu| accu << construct_concept(child)} 
    concept_paths_data = add_parent_child_paths(parent,children) 
end 
+1

Так что же ваша первая попытка решить эту проблему выглядеть ? – tadman

+0

https://gist.github.com/dasibre/0f1de48590064e4126440b7c4933cd10 первая попытка. – AfDev

+0

Идеально поставить такой код в свой вопрос. Вы можете редактировать, чтобы внести изменения. – tadman

ответ

0
def build_data(node, ctx = [], result = []) 
    id = node['id'] 
    children = node['children'] 

    branch = result.find{|h| h.has_key?(id)} 
    if branch.nil? 
    result.push({ 
     id => { 
     'id' => id, 
     'paths' => [] 
     } 
    }) 
    end 
    branch = result.find{|h| h.has_key?(id)} 
    branch[id]['paths'].unshift(
    [ctx, id].flatten.map do |ctx_id| 
     { 
     'id' => ctx_id 
     } 
    end 
) 

    if children.is_a?(Array) 
    children.each do |node| 
     new_ctx = ctx.dup 
     new_ctx.push(id) 
     nesting(node, new_ctx, result) 
    end 
    end 

    result 
end 
Смежные вопросы