Class: Tree

Inherits:
Object
  • Object
show all
Defined in:
lib/tree/tree.rb

Overview

## Tree

A simple Tree node Abstract class. it has a key and a list of children

##### Purpose

methods to traverse and find nodes

##### Example

“‘ruby

node = Tree.new(1, children: [Tree.new(2), Tree.new(3)])
node.key # => 1
node.children # => [Tree.new(2), Tree.new(3)]
```

Direct Known Subclasses

FeatureTree

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key, children: []) ⇒ Tree

Returns a new instance of Tree.



23
24
25
26
# File 'lib/tree/tree.rb', line 23

def initialize(key, children: [])
  @key = key
  @children = children
end

Instance Attribute Details

#childrenObject

Returns the value of attribute children.



21
22
23
# File 'lib/tree/tree.rb', line 21

def children
  @children
end

#keyObject

Returns the value of attribute key.



21
22
23
# File 'lib/tree/tree.rb', line 21

def key
  @key
end

Class Method Details

.add_node(root:, key:, parent_key:, child_key: nil) ⇒ Object

add node to the tree

Parameters:

  • root (Tree)
    • template’s root node

  • key (string)
    • key for the new node

  • parent_key (string)
    • key for its parent node

  • children (string)
    • key for its child node

Returns:

  • root - updated root node



76
77
78
79
80
81
82
83
84
# File 'lib/tree/tree.rb', line 76

def add_node(root:, key:, parent_key:, child_key: nil) # rubocop:disable Metrics/AbcSize
  parent = find(root, parent_key)
  child = find(root, child_key) if child_key
  parent.children = parent.children&.delete_if { |c| c.key == child_key } if child_key
  new_node = Tree.new(key, children: [child] || [])
  parent.children ||= []
  parent.children << new_node
  root
end

.find(node, key) {|node| ... } ⇒ Tree

Find the node by key

Parameters:

  • node (Tree)
    • root node

  • key (string)
    • key to find the node

Yields:

  • (node)

Returns:

  • (Tree)

    node - node with the key



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/tree/tree.rb', line 53

def find(node, key, &block)
  return nil unless node

  return node if node.key == key

  yield(node) if block_given?

  node.children&.map do |child|
    result = find(child, key, &block)
    return result if result
  end

  nil
end

.parse_template(json) ⇒ Object



107
108
109
110
111
112
113
114
# File 'lib/tree/tree.rb', line 107

def parse_template(json)
  return nil unless json
  children = json["children"]&.map do |child|
    parse_template(child)
  end

  self.new(json["key"], children: children)
end

.remove_node(root:, key:) ⇒ Object

Remove node from the templates’s root node

Parameters:

  • root (Tree)
    • template’s root node

  • key (string)
    • key for the new node

Returns:

  • root - updated root node

Raises:

  • (TypeError)


94
95
96
97
98
99
100
101
102
103
104
# File 'lib/tree/tree.rb', line 94

def remove_node(root:, key:)
  raise TypeError, 'Cannot delete root node' if root.key == key

  node_to_delete = find(root, key)
  raise TypeError, 'Cannot find the node to delete' unless node_to_delete

  parent = parent(root, key)

  parent.children.delete_if { |child| child.key == key }
  root
end

.traverse(node) {|node| ... } ⇒ Object

Traverse the tree and yield each node optional block to perform an action on each node

Parameters:

  • node (Tree)
    • node of a Tree

  • &block (Proc)
    • proc to execute client logic

Yields:

  • (node)

Returns:

  • nil



36
37
38
39
40
41
42
43
44
# File 'lib/tree/tree.rb', line 36

def traverse(node, &block)
  return nil unless node

  yield node if block_given?

  node.children&.map do |child|
    traverse(child, &block)
  end
end