2010-12-06 12 views
0

Ich habe ein YAML file of groups, Ich mag würde in eine MongoDB Sammlung mit Dokumenten wie {"name" => "golf", "parent" => "sports"} genannt Gruppen erhalten (Top-Level-Gruppen, wie Sport, wäre nur {"name" => "sports"} ohne parent.)rekursive DFS Ruby-Methode

Wir sind versuchen, traverse the nested hash, aber ich bin mir nicht sicher, ob es richtig funktioniert. Ich würde lieber eine rekursive Methode als einen Lambda-Proc verwenden. Was sollten wir ändern, damit es funktioniert?

Danke!

Matt

Antwort

2

Hier ist der Arbeitscode:

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 

Ansicht der Interests YAML.
Betrachten Sie die acani source.

+0

Das ist großartig. +1 –

0

Ihre Frage ist nur, wie Sie diesen Code konvertieren:

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]}) 
} 

..., ein Verfahren zu verwenden, anstatt eine Lambda? Wenn ja, dann:

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 

Wenn das nicht ist, was Sie bitten, helfen Sie bitte, zu klären.

+0

Danke, aber das Lambda funktionierte nicht, also würde nur die Umwandlung in eine Methode das Kernproblem nicht lösen. Meine Frage war, wie man es zum Laufen bringt (am besten mit einer Methode anstelle eines Lambda). Siehe [meine Antwort] (http://stackoverflow.com/questions/4368860/recursive-dfs-ruby-method/4524173#4524173). – ma11hew28