функция map для класса ruby ​​tree - PullRequest
0 голосов
/ 03 февраля 2011

Как бы я написал функцию карты для n-арного дерева в ruby?

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).) </p>

Я хочу написать функцию: map(&block), которая применяет block к каждому поддереву данного дерева (включая само дерево). То есть block примет Tree и вернет некоторый объект произвольного типа B. Результатом карты будет Tree с метками типа B.

Ответы [ 3 ]

3 голосов
/ 03 февраля 2011

Если вы можете реализовать метод each для своего класса, тогда include Enumerable, вы унаследуете все виды магического совершенства, включая map.

Реализуйте <=>, и вы получите еще больше.

Перечислимый ваш друг.


EDIT:

Если вы посмотрите, что происходит, когда вызывается 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 голос
/ 03 февраля 2011

Вместо выполнения block.call () вы также можете просто выдать:

  def map(&block)
    yield self
    children.each {|child| child.map(&block)}
  end
1 голос
/ 03 февраля 2011
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>
...