2016-06-28 49 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