Class: KeyTree::Forest

Inherits:
Array
  • Object
show all
Includes:
MetaData
Defined in:
lib/key_tree/forest.rb

Overview

A forest is a (possibly nested) collection of trees

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MetaData

#meta_data, #with_meta_data

Class Method Details

.[](*contents) ⇒ Object



11
12
13
14
15
# File 'lib/key_tree/forest.rb', line 11

def self.[](*contents)
  contents.reduce(Forest.new) do |result, content|
    result << KeyTree[content]
  end.sort!
end

Instance Method Details

#<=>(other) ⇒ Object

Trees are always smaller than forrests. Forests are compared by nesting depth, not number of trees.



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/key_tree/forest.rb', line 40

def <=>(other)
  return 0 if self == other

  case other
  when Forest
    depth <=> other.depth
  when Tree
    1
  else
    raise ArgumentError, 'only forests and trees are comparable'
  end
end

#[](key) ⇒ Object

For a numeric key, return the n:th tree in the forest

For a key path convertable key, return the closest match in the forest

When a closer tree contains a prefix of the key, this shadows any key path matches in trees further away, returning nil. This preserves the constraints that only leaves may contain a value.



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/key_tree/forest.rb', line 25

def [](key)
  case key
  when Numeric
    super(key)
  else
    detect do |tree_or_forest|
      return tree_or_forest[key] if tree_or_forest.key?(key)
      return nil if tree_or_forest.prefix?(key)
    end
  end
end

#depthObject

The nesting depth of a forest



54
55
56
57
58
# File 'lib/key_tree/forest.rb', line 54

def depth
  reduce(1) do |result, tree_or_forest|
    [result, content_depth(tree_or_forest) + 1].max
  end
end

#flattenObject

Flattening a forest produces a tree with the equivalent view of key paths



70
71
72
73
74
75
76
77
78
79
# File 'lib/key_tree/forest.rb', line 70

def flatten
  reduce(Tree[]) do |result, tree_or_forest|
    case tree_or_forest
    when Forest
      tree_or_forest.flatten.merge(result)
    else
      tree_or_forest.merge(result)
    end
  end
end

#key?(key) ⇒ Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/key_tree/forest.rb', line 60

def key?(key)
  any? { |tree_or_forest| tree_or_forest.key?(key) }
end

#prefix?(key) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/key_tree/forest.rb', line 64

def prefix?(key)
  any? { |tree_or_forest| tree_or_forest.prefix?(key) }
end