2013-04-26 85 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