class KeyTree::Forest

A forest is a (possibly nested) collection of trees

Public Class Methods

[](*contents) click to toggle source
# 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

Public Instance Methods

[](key) click to toggle source

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.

Calls superclass method
# 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) → value click to toggle source
fetch(key, default) → value
fetch(key) { |key| } → value

Fetch a value from a forest

The first form raises a KeyError unless key has a value.

# 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) click to toggle source

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

# File lib/key_tree/forest.rb, line 90
def flatten(&merger)
  trees.reverse_each.reduce(Tree[]) do |result, tree|
    result.merge!(tree, &merger)
  end
end
has_key?(key)
Alias for: key?
has_key_path?(key)
Alias for: key_path?
has_prefix?(key)
Alias for: prefix?
include?(needle) click to toggle source
Calls superclass method
# File lib/key_tree/forest.rb, line 79
def include?(needle)
  case needle
  when Tree, Forest
    super(needle)
  else
    key_path?(needle)
  end
end
key?(key) click to toggle source
# File lib/key_tree/forest.rb, line 64
def key?(key)
  trees.lazy.any? { |tree| tree.key?(key) }
end
Also aliased as: has_key?
key_path?(key) click to toggle source
# File lib/key_tree/forest.rb, line 74
def key_path?(key)
  trees.lazy.any? { |tree| tree.key_path?(key) }
end
Also aliased as: has_key_path?
key_paths() click to toggle source

Return all visible key paths in the forest

# File lib/key_tree/forest.rb, line 110
def key_paths
  trees.reduce(Set.new) { |result, tree| result.merge(tree.key_paths) }
end
prefix?(key) click to toggle source
# File lib/key_tree/forest.rb, line 69
def prefix?(key)
  trees.lazy.any? { |tree| tree.prefix?(key) }
end
Also aliased as: has_prefix?
trees() click to toggle source

Return a breadth-first Enumerator for all the trees in the forest, and any nested forests

# File lib/key_tree/forest.rb, line 98
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