Class: KeyTree::Forest
- Inherits:
-
Array
- Object
- Array
- KeyTree::Forest
- 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
-
#[](key) ⇒ Object
For a numeric key, return the n:th tree in the forest.
-
#fetch(key, *default) ⇒ Object
Fetch a value from a forest.
-
#flatten(&merger) ⇒ Object
Flattening a forest produces a tree with the equivalent view of key paths.
- #include?(needle) ⇒ Boolean
- #key?(key) ⇒ Boolean (also: #has_key?)
- #key_path?(key) ⇒ Boolean (also: #has_key_path?)
-
#key_paths ⇒ Object
Return all visible key paths in the forest.
- #prefix?(key) ⇒ Boolean (also: #has_prefix?)
-
#trees ⇒ Object
Return a breadth-first Enumerator for all the trees in the forest, and any nested forests.
Methods included from MetaData
Class Method Details
.[](*contents) ⇒ Object
16 17 18 19 20 |
# File 'lib/key_tree/forest.rb', line 16 def self.[](*contents) contents.reduce(Forest.new) do |result, content| result << content.to_key_wood end end |
Instance Method Details
#[](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.
33 34 35 36 37 38 39 40 41 42 |
# File 'lib/key_tree/forest.rb', line 33 def [](key) return super(key) if key.is_a?(Numeric) trees.lazy.each do |tree| result = tree[key] return result unless result.nil? break if tree.prefix?(key) end nil end |
#fetch(key, *default) ⇒ Object
Fetch a value from a forest
:call-seq:
fetch(key) => value
fetch(key, default) => value
fetch(key) { |key| } => value
The first form raises a KeyError unless key has a value.
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/key_tree/forest.rb', line 52 def fetch(key, *default) trees.lazy.each do |tree| catch do |ball| return tree.fetch(key) { throw ball } end end return yield(key) if block_given? return default.first unless default.empty? raise KeyError, %(key not found: "#{key}") end |
#flatten(&merger) ⇒ Object
Flattening a forest produces a tree with the equivalent view of key paths
89 90 91 92 93 |
# File 'lib/key_tree/forest.rb', line 89 def flatten(&merger) trees.reverse_each.reduce(Tree[]) do |result, tree| result.merge!(tree, &merger) end end |
#include?(needle) ⇒ Boolean
78 79 80 81 82 83 84 85 |
# File 'lib/key_tree/forest.rb', line 78 def include?(needle) case needle when Tree, Forest super(needle) else key_path?(needle) end end |
#key?(key) ⇒ Boolean Also known as: has_key?
63 64 65 |
# File 'lib/key_tree/forest.rb', line 63 def key?(key) trees.lazy.any? { |tree| tree.key?(key) } end |
#key_path?(key) ⇒ Boolean Also known as: has_key_path?
73 74 75 |
# File 'lib/key_tree/forest.rb', line 73 def key_path?(key) trees.lazy.any? { |tree| tree.key_path?(key) } end |
#key_paths ⇒ Object
Return all visible key paths in the forest
108 109 110 |
# File 'lib/key_tree/forest.rb', line 108 def key_paths trees.reduce(Set.new) { |result, tree| result.merge(tree.key_paths) } end |
#prefix?(key) ⇒ Boolean Also known as: has_prefix?
68 69 70 |
# File 'lib/key_tree/forest.rb', line 68 def prefix?(key) trees.lazy.any? { |tree| tree.prefix?(key) } end |
#trees ⇒ Object
Return a breadth-first Enumerator for all the trees in the forest, and any nested forests
97 98 99 100 101 102 103 104 105 |
# File 'lib/key_tree/forest.rb', line 97 def trees Enumerator.new do |yielder| remaining = [self] remaining.each do |woods| next yielder << woods if woods.is_a?(Tree) woods.each { |wood| remaining << wood } end end end |