module Tins::HashBFS

def bfs(visit_internal: false, &block)

Returns:
  • (self) - returns the receiver

Other tags:
    Example: bfs { |index, value| … } # performs a breadth-first search on the object's structure -

Raises:
  • (ArgumentError) - if no &block argument was provided

Other tags:
    Yield: - yields each element's index and value to the block

Parameters:
  • visit_internal (true, false) -- whether to visit internal hashes or arrays
def bfs(visit_internal: false, &block)
  block or raise ArgumentError, 'require &block argument'
  self.seen = {}
  queue     = []
  queue.push([ nil, self ])
  while (index, object = queue.shift)
    case
    when seen[object.__id__]
      next
    when Hash === object
      seen[object.__id__] = true
      object.each do |k, v|
        queue.push([ k, convert_to_hash_or_ary(v) ])
      end
      visit_internal or next
    when Array === object
      seen[object.__id__] = true
      object.each_with_index do |v, i|
        queue.push([ i, convert_to_hash_or_ary(v) ])
      end
      visit_internal or next
    end
    block.(index, object)
  end
  self
ensure
  self.seen = nil
end

def convert_to_hash_or_ary(object)

Returns:
  • (Hash, Array, Object) - The converted object or itself if not convertible

Parameters:
  • object (Object) -- The object to convert
def convert_to_hash_or_ary(object)
  case
  when object.respond_to?(:to_hash)
    object.to_hash
  when object.respond_to?(:to_ary)
    object.to_ary
  else
    object
  end
end