【问题标题】:Adding data of an unknown type to a hash将未知类型的数据添加到哈希中
【发布时间】:2011-08-10 10:09:31
【问题描述】:

Ruby 似乎是一种特别适合解决这个问题的语言,但我没有找到一种优雅的方法来解决这个问题。我想要的是一种接受一个值并将其添加到哈希中的方法,如果密钥已经存在,则对如何添加它有特定要求:

将 'foo' 添加到 :key1

{:key1 => 'foo'}

将'bar'添加到:key1

{:key1=> 'foobar'}

将 ['foo'] 添加到 :key2

{:key2 = ['foo']}

将 ['bar'] 添加到 :key2

{:key2 => [['foo'], ['bar']]

将 {:k1 => 'foo'} 添加到 :key3

{:key3 => {:k1 => 'foo'}}

将 {:k2 => 'bar'} 添加到 :key3

{:key3 => {:k1 => 'foo', :k2 => 'bar'}}

现在我可以做到这一点,但它看起来很草率,不像惯用的 Ruby。有什么好的方法可以做到这一点?

【问题讨论】:

  • 不是我完全确定你在这里要做什么,但为什么数组部分不是{:key2 => ['foo', 'bar']}
  • 如果你刚刚在 Hash 上定义了#+ 来做#merge,你就可以使用它。定义添加(h,k,v); h[k] ? h[k] += v : h[k] = v;结束
  • 这不是一个很好的例子,但我只是表明它必须是一个数组数组。

标签: ruby-on-rails ruby


【解决方案1】:

为了使它更像 Ruby,您可能希望扩展 Hash 类以提供这种全面的功能,或者为这个特定目的创建自己的子类。例如:

class FancyHash < Hash
  def add(key, value)
    case (self[key])
    when nil
      self[key] = value
    when Array
      self[key] = [ self[key], value ]
    when Hash
      self[key].merge!(value)
    else
      raise "Adding value to unsupported #{self[key].class} structure"
    end
  end
end

这将取决于您对“添加”含义的确切解释,因为您的示例确实看起来有些简单,并且没有说明当您将哈希添加到预先存在的数组时会发生什么。

这个想法是,您定义一个处理程序,该处理程序可以容纳尽可能多的合理可能性,如果您无法管理,则抛出异常。

【讨论】:

  • 这些例子可能很简单,但就是我的要求所需要的。顺便说一句,这是题外话,但是如果您要扩展内置类,那么它会在 Rails 项目中放在哪里?
  • 你通常会把它们放在你的 lib 目录中。
  • 实际上最终把它放在了我的 config/initializers 目录中。需要在我的任何代码加载之前加载它吗?
  • config/initializers 是小“扩展”脚本的好地方,但如果它们增长到超过几十行,则使初始化程序成为加载完整 lib/ 托管库的挂钩。
【解决方案2】:

如果您想利用 oop 的多态特性,您可能需要这样做:

class Object; def add_value v; v end end
class String; def add_value v; self+v end end  # or concat(v) for destructive
class Array; def add_value v; [self, v] end end # or replace([self.dup, v]) for destructive
class Hash; def add_value v; merge(v) end end  # or merge!(v) for destructive

class Hash
  def add k, v; self[k] = self[k].add_value(v) end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2021-03-04
    • 2013-05-27
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多