Sha256: 7e421a3ff951cf89c2de2bbe34ae83fb036141ad2e4de7b67e3cf2154075cce2

Contents?: true

Size: 1.85 KB

Versions: 20

Compression:

Stored size: 1.85 KB

Contents

class Hash::DeepHashConstructor
  attr_accessor :separator

  def initialize(separator)
    @separator = separator
  end

  def deep_hash(object)
    if object.is_a? Array
      array_deep_hash(object)
    elsif object.is_a? Hash
      hash_deep_hash(object)
    else
      object
    end
  end

  private

  def array_deep_hash(array)
    array.map { |v| v.is_a?(Hash) ? deep_hash(v) : v }
  end

  def hash_deep_hash(hash)
    {}.tap do |new_hash|
      hash.each do |k, v|
        base_key, child_key = split_key(k, separator)
        set_deep_hash_positioned_value(new_hash, base_key, v, child_key)
      end

      new_hash.each do |k, v|
        new_hash[k] = deep_hash(v)
      end
    end
  end

  def split_key(key, separator)
    separator_rxp = (separator == '.') ? "\\#{separator}" : separator
    skipper = "[^#{separator}]"
    regexp = Regexp.new("^(#{skipper}*)#{separator_rxp}(.*)")
    match = key.match(regexp)

    match ? match[1..2] : key
  end

  def set_deep_hash_array_value(hash, base_key, index, value, key = nil)
    key_without_index = base_key.gsub("[#{index}]", '')
    hash[key_without_index] ||= []

    if key.nil?
      hash[key_without_index][index] = value
    else
      hash[key_without_index][index] ||= {}
      hash[key_without_index][index][key] = value
    end
  end

  def set_deep_hash_positioned_value(new_hash, base_key, v, child_key)
    index = array_index(base_key)

    if index
      set_deep_hash_array_value(new_hash, base_key, index, v, child_key)
    else
      set_deep_hash_value(new_hash, base_key, v, child_key)
    end
  end

  def array_index(key)
    match = key.match(/\[([^)]+)\]/)
    if match
      match[1].to_i
    end
  end

  def set_deep_hash_value(hash, base_key, value, key = nil)
    if key.nil?
      hash[base_key] = value
    else
      hash[base_key] ||= {}
      hash[base_key][key] = value
    end
  end
end

Version data entries

20 entries across 20 versions & 2 rubygems

Version Path
darthjee-core_ext-1.5.6 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.5.5 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.5.4 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.5.3 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.5.2 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.5.1 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.5.0 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.4.1 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.4.0 lib/darthjee/core_ext/hash/deep_hash_constructor.rb
darthjee-core_ext-1.3.1 lib/hash/deep_hash_constructor.rb
darthjee-core_ext-1.3.0 lib/hash/deep_hash_constructor.rb
darthjee-core_ext-1.2.6 lib/hash/deep_hash_constructor.rb
bidu-core_ext-1.2.5 lib/hash/deep_hash_constructor.rb
bidu-core_ext-1.2.4 lib/hash/deep_hash_constructor.rb
bidu-core_ext-1.2.3 lib/hash/deep_hash_constructor.rb
bidu-core_ext-1.2.2 lib/hash/deep_hash_constructor.rb
bidu-core_ext-1.2.1 lib/hash/deep_hash_constructor.rb
bidu-core_ext-1.2.0 lib/hash/deep_hash_constructor.rb
bidu-core_ext-1.1.1 lib/hash/deep_hash_constructor.rb
bidu-core_ext-1.0.0 lib/hash/deep_hash_constructor.rb