我如何为ruby中的n-ary树编写一个map函数?
class Tree
def children() return @children end
def label() return @label end
def initialize(label, children)
@label = label
@children = children
end
def map(&block)
# TODO
end
end
(注意children
是一个任意列表(不一定是长度< = 2)。)
我想写一个函数:map(&block)
,它将block
应用于给定树的每个子树(包括树本身)。也就是说,block
将接受Tree
并返回任意类型的对象B
。地图的结果是Tree
,其标签类型为B
。
答案 0 :(得分:3)
如果您可以为您的班级实施each
方法,那么include Enumerable
,您将继承各种神奇的善良,包括map
。
实施<=>
,您将获得更多收益。
Enumerable是你的朋友。
编辑:
如果你看一下调用Hash#map
时会发生什么,哈希会被转换成一个数组数组:
>> hash = {'a' => 1, 'b' => 2} #=> {"a"=>1, "b"=>2}
>> hash.map{|n| n} #=> [["a", 1], ["b", 2]]
开发人员可以在之后进行扫描,并可选择重建转换后的哈希值。由于Hash[]
的工作原理,这很容易。
>> Hash[*hash.map{|n| n}.flatten] #=> {"a"=>1, "b"=>2}
如果是我,我会写一种方法来获取数组,并重建你的树。这样,您的each
方法将允许include Enumerable
创建map
。你可以调用它,然后动态重建树。看看Hash#[]
是如何使用的,你应该开始为你的代码实现类似的东西。
答案 1 :(得分:1)
def map(&block)
Tree.new(block.call(self), children.map{|x| x.map(&block)})
end
以下是一个示例用法:
t.map{|x| puts(x.label + " -> " + x.children.map{|i| i.label}.join(" "))}
对于树中的每个节点,此形式的本地树信息为:
<label> -> <child label 1> <child label 2> <child label 3>
答案 2 :(得分:1)
除了执行block.call()之外,您还可以产生:
def map(&block)
yield self
children.each {|child| child.map(&block)}
end