Module: Plushie::Tree::Search

Defined in:
lib/plushie/tree/search.rb

Overview

Tree search and query functions.

All methods accept a Node or Array of Nodes as the tree root. Search is depth-first.

Class Method Summary collapse

Class Method Details

.exists?(tree, id) ⇒ Boolean

Check if a node with the given ID exists.

Parameters:

  • tree (Node, Array<Node>, nil)
  • id (String)

Returns:

  • (Boolean)


41
42
43
# File 'lib/plushie/tree/search.rb', line 41

def self.exists?(tree, id)
  !find(tree, id).nil?
end

.find(tree, id) ⇒ Node?

Find a node by ID (depth-first).

Supports both fully-qualified IDs ("main#form/email") and local names ("email"). Local names match by suffix: a search for "email" matches "main#form/email".

Parameters:

  • tree (Node, Array<Node>, nil)
  • id (String)

    node ID to find

Returns:



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/plushie/tree/search.rb', line 19

def self.find(tree, id)
  return nil if tree.nil?
  trees = tree.is_a?(Array) ? tree : [tree]
  exact = id.include?("#")

  trees.each do |node|
    if exact
      return node if node.id == id
    elsif id_matches?(node.id, id)
      return node
    end
    found = find(node.children, id)
    return found if found
  end

  nil
end

.find_all(tree) {|Node| ... } ⇒ Array<Node>

Find all nodes matching a predicate (depth-first).

Parameters:

Yields:

  • (Node)

    predicate block

Returns:



78
79
80
81
82
83
84
85
86
87
# File 'lib/plushie/tree/search.rb', line 78

def self.find_all(tree, &predicate)
  return [] if tree.nil?
  result = [] #: Array[Node]
  trees = (tree.is_a?(Array) ? tree : [tree]).compact
  trees.each do |node|
    result << node if predicate.call(node)
    result.concat(find_all(node.children, &predicate))
  end
  result
end

.find_first(tree) {|Node| ... } ⇒ Node?

Find the first node matching a predicate (depth-first).

Parameters:

Yields:

  • (Node)

    predicate block

Returns:



63
64
65
66
67
68
69
70
71
72
# File 'lib/plushie/tree/search.rb', line 63

def self.find_first(tree, &predicate)
  return nil if tree.nil?
  trees = (tree.is_a?(Array) ? tree : [tree]).compact
  trees.each do |node|
    return node if predicate.call(node)
    found = find_first(node.children, &predicate)
    return found if found
  end
  nil
end

.ids(tree) ⇒ Array<String>

Return all node IDs in depth-first order.

Parameters:

Returns:

  • (Array<String>)


48
49
50
51
52
53
54
55
56
57
# File 'lib/plushie/tree/search.rb', line 48

def self.ids(tree)
  return [] if tree.nil?
  result = [] #: Array[String]
  trees = (tree.is_a?(Array) ? tree : [tree]).compact
  trees.each do |node|
    result << node.id
    result.concat(ids(node.children))
  end
  result
end