使用ruby创建类继承层次结构

时间:2014-11-13 13:57:20

标签: ruby

我想使用ruby来创建类继承层次结构。我有grep类名及其父类名,如下所示: [[B,A],[C,A],[E,D],[F,B] ......]

[B,A] A是B的父类,而根类不仅仅是一个,如A或D. 数组中的元素只是字符串,如A,B,C ......

我想创建一个像这样的继承层次结构图:

[
    A=>[
          B=>[F],
          C
        ],
    D=>[E] 
]

图形格式不严格,可以证明层次结构正常。

我尝试使用循环递归放置节点,但效率太低。有没有人可以帮助我,或者有一些宝石来解决这个问题?

所有我想知道的是clas inherirance层次结构,所以无论你如何解决这个问题。

感谢@Max和@Gabriel de Oliveira回答我的问题!我已经解决了这个问题。 它可能很难看,但它确实有效。

class Node
    attr_accessor :name, :parent, :children
    def initialize(name)
        @name = name
        @parent = nil
        @children = Set.new
    end

    def <=>(other)
        if other.name == self.name
            return 0
        end

        return nil
    end

    def ==(other)
        if other.name == self.name
            return true
        end

        return false
    end

    def inspect
        desc = ""
        desc << "{" if @children.length > 0
        desc << %("#{@name}")
        if @children.count > 0
            desc << ":["
            children_arr = @children.to_a
            children_arr.to_a.each_index do |index|
                desc << ',' if index > 0
                desc << children_arr[index].inspect
            end
            desc << "]"
        end
        desc << "}" if @children.length > 0

        return desc
    end
end


str = string_from_file(file_path)
arr = JSON.parse(str)

nodes = {}

# create nodes set
arr.each do |item|
    name = item[0]
    parent = item[1]

    nodes[name] = Node.new(name)
    nodes[parent] = Node.new(parent)
end

# bind relationship with nodes
arr.each do |item|
    node = nodes[item[0]]
    parent = nodes[item[1]]

    if !parent.nil?
        node.parent = parent
        parent.children << node
    end
end

# filter the root nodes
roots = []
nodes.each_value do |node|
    roots << node if node.parent.nil?
end

puts roots

2 个答案:

答案 0 :(得分:0)

您可以使用元编程来完成此操作。 B = Class.new(A)创建了一个继承自BA的{​​{1}}类,Object.const_set可以动态访问常量。唯一棘手的问题是以正确的顺序创建类,但这可以通过递归来解决。

Object.const_get

答案 1 :(得分:0)

要将输入数组转换为嵌套哈希,您可以按照以下几行实现:

def process(input)
  return {} if input.empty?

  base_classes, rest = input.partition {|value| value.is_a? Class }

  ret_val = {}

  base_classes.each do |klass|
    ret_val[klass], rest = rest.partition {|value| value.last == klass }
    ret_val[klass] = ret_val[klass].map(&:first)
  end 

  ret_val.each {|klass, classes| ret_val[klass] = process(classes + rest) }
end

然后给定所有的clases,并清理你的data数组(例如它不包含[X, Z]之类的无效元素:

data = [A, [B, A], [C, A], D, [E, D], [F, B]]
process(data)  #=> {A=>{B=>{F=>{}}, C=>{}}, D=>{E=>{}}}