ruby - 在 Ruby 中,如何将此字符串格式转换为哈希值

标签 ruby

字符串格式是这样的

 "a.b.c = 1"
 "a.b.d = 2"
=> its hash will be
=> {'a'=> {'b' => {'c'=>1, 'd'=>2 } } }

数组变得很棘手

 "a.e[0].f = 1"
 "a.e[0].g = 2"
 "a.e[1].h = 3"
 => its hash will be
 => {'a' => {'e' => [{'f'=>1, 'g'=>2}, {'h'=>3}] } }

我编写了一个不处理带有太多 if-else 检查的数组的版本

def construct
  $output[$words[0]] = {} unless $output.has_key?($words[0])
  pointer = $output[$words[0]]
  $words[1..-2].each do |word|
    pointer[word] = {} unless pointer.has_key?(word)
    pointer = pointer[word]
  end
  pointer[$words[-1]] = 1
end

$output = {}
$words = ['a', 'b', 'c']
construct
$words = ['a', 'b', 'd']
construct
p $output

数组版本更糟糕。在 Ruby 中是否有更好的方法来解决这个问题?

最佳答案

不像我想象的那么简单。这是我想到的:

class Hash
  def hash_merge(other)
    update(other) do | key, val_self, val_other |
      case val_self
      when Hash
        val_self.hash_merge val_other
      when Array
        val_self += [nil] * (val_other.length - val_self.length)
        val_self.zip(val_other).map { | a, b | a && b ? a.hash_merge(b) : a || b }
      else
        # error
      end
    end
  end
end

# parses a string of the form "a.e[1].g = 2" to a hash {"a" => {"e" => [nil , {"g" => 2}]}}
def construct_string(s)
  if s =~ /\A\s*(\S+)\s+=\s+(\d+)\z/
    s1, s2 = $1, $2
    s1.split('.').reverse.inject(s2.to_i) do | hash, name |
      if name =~ /\[(\d+)\]\z/
        name, idx = $~.pre_match, $1.to_i
        array = []
        array[idx] = hash
        { name => array }
      else
        { name => hash }
      end
    end
  else 
    # error
  end
end

# parses an array of string and merges the resulting hashes
def construct(s)
  s.map { | e | construct_string(e) }.inject(&:hash_merge)
end

ins = ["a.e[0].f = 1",
       "a.e[0].g = 2",
       "a.e[1].h = 3"]

p construct(ins)   # {"a"=>{"e"=>[{"f"=>1, "g"=>2}, {"h"=>3}]}}

关于ruby - 在 Ruby 中,如何将此字符串格式转换为哈希值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30841007/

相关文章:

ruby - ex.class应该等于什么?

ruby - 如何突出显示 if else 以atom/sublime结尾?

ruby - Jekyll 中的隔离代码块

ruby-on-rails - 电子邮件附件不适用于邮戳

ruby - 输出到控制台,同时在 ruby​​ 中保留用户输入

ruby - Chef 没有运行 apt (apt-get update) 配方。返回 100

ruby-on-rails - 复制/克隆 ActiveStorage 属性

ruby - 迭代 Jekyll 中的子类别

ruby-on-rails - git clone 我的 rails 项目后出现错误

c# - 与 C# 相比,您会强调 Ruby 的哪些语言特性?