2013-04-26 84 views
-2

我需要一個我稱之爲shake_tree的操作。我已經使用遞歸算法來實現它,只使用基本的紅寶石的Fortran(引用舊報價「你可以在的Fortran代碼的任何語言。」),但我嫌疑有一個更簡潔和慣用的紅寶石方式如何實現樹形搖動器操作?

因爲我不知道這個操作的通用名稱,所以讓我簡單描述一下。我有這樣的例子哈希散列:

{ 
    "-cutoff:" => 
    { 
    :flag => {:set_ie1 => [:useCutoff, true]}, 
    :arg => {:vector_ie1 => :double} 
    }, 
    "-depth:" => 
    { 
    :flag => {:set_ie2 => [:useInconsistent, true]}, 
    :arg => :double, 
    :default => 2.0 
    }, 
    "-maxclust:" => 
    { 
    :flag => {:set_ie3 => [:useCutoff, false]}, 
    :arg => {:vector_ie2 => :index} 
    }, 
    :fn => "arrayTypeOptions" 
} 

有嵌入的樹結構中像:vector_ie1:set_ie3獨特的符號。我需要刪除除了從根部到符號之間的路徑以外的樹的所有分支。鑑於上面的例子:

shake_tree(specs, :vector_ie1) 

將返回:

{ 
    "-cutoff:" => 
    { 
    :flag => {:set_ie1 => [:useCutoff, true]}, 
    :arg => {:vector_ie1 => :double} 
    } 
} 

shake_tree(specs, :set_ie2) 

將返回:

{ 
    "-depth:" => 
    { 
    :flag => {:set_ie2 => [:useInconsistent, true]}, 
    :arg => :double, 
    :default => 2.0 
    } 
} 

如何將一個更有經驗的紅寶石編碼器的方法是什麼?

+0

爲什麼不使用像[RubyTree](http://rubytree.rubyforge.org/rdoc/index.html)這樣的樹庫?它有一個'parentage'方法,會給你這個。 – 2013-04-26 01:55:45

+0

@MarkThomas:感謝您的鏈接,但一目瞭然看起來像是過度殺傷。 ** ruby​​ ** DSL的全部想法是讓** ruby​​ **完成大部分工作......現在,我的DSL的「解析器」包含在「源」字符串上調用「vMATCodeMonkey#instance_eval」! :-) – 2013-04-26 02:32:30

回答

1

這是我的遞歸實現。我決定把它shake_tree保持的RubyMine的拼寫檢查開心(因爲我喜歡的shake_tree specs key聲音):

def shake_tree(specs, key) 
    parent = find_parent(specs, key) 
    parent ? { parent => specs[parent] } : nil 
end 

def find_parent(specs, key, keypath = []) 
    specs.each do |k, v| 
    if k == key 
     return (keypath + [k])[0] 
    elsif v.is_a?(Hash) 
     branch = find_parent(v, key, keypath + [k]) 
     if !branch.nil? 
     return branch 
     end 
    end 
    end 
    nil 
end 

這正好返回上面指定的輸出。

我仍然很想知道這是否有一個共同的名稱。

+0

我太遲了15秒..所以我會貼我的答案在這裏。對不起,壓縮。但註釋很緊密 – quetzalcoatl 2013-04-26 08:13:13

+0

我不完全確定你的數據是否真的是一棵樹。這個例子看起來更像是KEY => ENTRY形式的結構化數據條目的集合/列表,並且Entry或者是定義良好的結構的簡單值。當然,嚴格來說,它是一棵樹,但不僅僅是一棵樹:)除非你的「條目」比簡單值或簡單哈希更復雜,否則你可以很容易地**過濾**,只是通過SELECT或拒絕函數不遞歸。 – quetzalcoatl 2013-04-26 08:13:30

+1

示例(data = your-input-data):'data.select {| key,entry | [:flag,:arg] .map {| k | entry [k] .keys rescue nil} .flatten.include?(:vector_ie2)}' – quetzalcoatl 2013-04-26 08:14:04