class UKPostcode::Tree
Public Class Methods
new(tree = {})
click to toggle source
# File lib/uk_postcode/tree.rb, line 3 def initialize(tree = {}) @root = tree end
Public Instance Methods
compress()
click to toggle source
# File lib/uk_postcode/tree.rb, line 11 def compress self.class.new(compress_node(@root)) end
filter(leaf_value)
click to toggle source
# File lib/uk_postcode/tree.rb, line 15 def filter(leaf_value) self.class.new(filter_node(@root, leaf_value)) end
insert(path, value)
click to toggle source
# File lib/uk_postcode/tree.rb, line 7 def insert(path, value) path[0..-2].inject(@root) { |n, p| n[p] ||= {} }[path.last] = value end
regexp()
click to toggle source
# File lib/uk_postcode/tree.rb, line 19 def regexp Regexp.new('^' + node_regexp(@root)) end
to_h()
click to toggle source
# File lib/uk_postcode/tree.rb, line 23 def to_h @root end
Private Instance Methods
compress_node(node)
click to toggle source
# File lib/uk_postcode/tree.rb, line 37 def compress_node(node) if leaf?(node) node else comp = Hash[node.map { |k, v| [k, compress_node(v)] }] contains_identical_leaves?(comp) ? comp.values.first : comp end end
contains_identical_leaves?(node)
click to toggle source
# File lib/uk_postcode/tree.rb, line 33 def contains_identical_leaves?(node) node.values.all? { |t| leaf?(t) } && node.values.uniq.length == 1 end
filter_node(node, leaf_value)
click to toggle source
# File lib/uk_postcode/tree.rb, line 46 def filter_node(node, leaf_value) if node == leaf_value node elsif leaf?(node) nil else h = Hash[node.map { |k, v| [k, filter_node(v, leaf_value)] }. select { |_, v| v }] h.empty? ? nil : h end end
leaf?(node)
click to toggle source
# File lib/uk_postcode/tree.rb, line 29 def leaf?(node) node.is_a?(Symbol) end
node_regexp(node)
click to toggle source
# File lib/uk_postcode/tree.rb, line 58 def node_regexp(node) if leaf?(node) '' else segments = node.map { |k, v| k + node_regexp(v) } if segments.length > 1 if segments.all? { |s| s.length == 1 } '[' + segments.join('') + ']' else '(?:' + segments.join('|') + ')' end else segments.first end end end