2010-12-06 10 views
0

J'ai un YAML file of groups que je voudrais entrer dans un groupe appelé collection MongoDB avec des documents comme {"name" => "golf", "parent" => "sports"} (groupes de haut niveau, comme le sport, serait tout simplement {"name" => "sports"} sans parent.)méthode récursive DFS Ruby

Nous sommes essayer de traverse the nested hash, mais je ne suis pas sûr si cela fonctionne correctement. Je préférerais utiliser une méthode récursive qu'un proc de lambda. Que devrions-nous changer pour le faire fonctionner?

Merci!

Matt

Répondre

2

est ici le code de travail:

require 'mongo' 
require 'yaml' 

conn = Mongo::Connection.new 
db = conn.db("acani") 
interests = db.collection("interests") 
@@interest_id = 0 
interests_hash = YAML::load_file('interests.yml') 

def interests.insert_interest(interest, parent=nil) 
    interest_id = @@interest_id.to_s(36) 
    if interest.is_a? String # base case 
    insert({:_id => interest_id, :n => interest, :p => parent}) 
    @@interest_id += 1 
    else # it's a hash 
    interest = interest.first # get key-value pair in hash 
    interest_name = interest[0] 
    insert({:_id => interest_id, :n => interest_name, :p => parent}) 
    @@interest_id += 1 
    interest[1].each do |i| 
     insert_interest(i, interest_name) 
    end 
    end 
end 

interests.insert_interest interests_hash 

Voir les Interests YAML. Voir le acani source.

+0

C'est génial. +1 –

0

Votre question est juste comment convertir ce code:

insert_enumerable = lambda {|obj, collection| 
    # obj = {:value => obj} if !obj.kind_of? Enumerable 
    if(obj.kind_of? Array or obj.kind_of? Hash) 
     obj.each do |k, v| 
     v = (v.nil?) ? k : v 
     insert_enumerable.call({:value => v, :parent => obj}, collection) 
     end 
    else 
     obj = {:value => obj} 
    end 
    # collection.insert({name => obj[:value], :parent => obj[:parent]}) 
    pp({name => obj[:value], :parent => obj[:parent]}) 
} 

... d'utiliser une méthode plutôt qu'une lambda? Si oui, alors:

def insert_enumerable(obj, collection) 
    # obj = {:value => obj} if !obj.kind_of? Enumerable 
    if(obj.kind_of? Array or obj.kind_of? Hash) 
     obj.each do |k, v| 
     v = (v.nil?) ? k : v 
     insert_enumerable({:value => v, :parent => obj}, collection) 
     end 
    else 
     obj = {:value => obj} 
    end 
    # collection.insert({name => obj[:value], :parent => obj[:parent]}) 
    pp({name => obj[:value], :parent => obj[:parent]}) 
end 

Si ce n'est pas ce que vous demandez, s'il vous plaît aider à clarifier.

+0

Merci, mais le lambda ne fonctionnait pas, donc simplement le convertir en une méthode ne résoudrait pas le problème de base. Ma question était de savoir comment le faire fonctionner (de préférence avec une méthode au lieu d'un lambda). Voir [ma réponse] (http://stackoverflow.com/questions/4368860/recursive-dfs-ruby-method/4524173#4524173). – ma11hew28