为 Ruby 上的散列编写自定义方法?在 rails

Writing custom method for a hash on Ruby? on rails

我正在尝试(实际上成功了,但我不明白它是如何工作的)在我的模型中为散列编写自定义方法(我正在 Ruby Rails 6).

我的哈希看起来像这样

my_hash = { 
 [['name_1', 'slug_1']=>value_1],
 [['name_2', 'slug_2']=>value_2],
 [['name_1', 'slug_1']=>value_3],
 [['name_2', 'slug_2']=>value_4] 
}

所以基本上是数组的散列。您注意到 'keys' 是重复多次但具有不同值的数组。我想要实现的是编写一个自定义方法,将所有键“连接”在一个键中,它将分配一组值,所以基本上我应该能够得到:

my_hash = { 
 ['name_1', 'slug_1']=>"values": [value_1, value_3],
 ['name_2', 'slug_2']=>"values": [value_2, value_4]
}

为此,我有这段代码,我多次使用它:

my_hash.inject({}) do |hash, record|
  # each record has the following format => [["unit_name", "axis.slug"]=>average_value(float)]
  keys, value = record
  # now keys has ["unit_name", "axis.slug"] and values equals average_value
  hash[keys.first] ||= {}
  hash[keys.first][keys.last] = value.to_f
  hash
end

因为我多次使用这个,所以我想写一个自定义方法,所以我做了:

  def format_hash_data my_hash
    my_hash.inject({}) do |hash, record|
      # each record has the following format => [["unit_name", "axis.slug"]=>average_value(float)]
      keys, value = record
      # now keys has ["unit_name", "axis.slug"] and values equals average_value
      hash[keys.first] ||= {}
      hash[keys.first][keys.last] = value.to_f
      hash
    end
  end

并像这样使用它:my_hash = format_hash_data(my_hash) 但没有成功(它抛出一个错误,指出 'format_hash_data' 不是 class 的有效方法)。

于是我胡乱摆弄,在方法名后面加上了'self',剩下:

  def self.format_hash_data my_hash
    my_hash.inject({}) do |hash, record|
      # each record has the following format => [["unit_name", "axis.slug"]=>average_value(float)]
      keys, value = record
      # now keys has ["unit_name", "axis.slug"] and values equals average_value
      hash[keys.first] ||= {}
      hash[keys.first][keys.last] = value.to_f
      hash
    end
  end

令我惊讶的是,它在使用 my_hash = format_hash_data(my_hash)

时完美运行

我真的不明白为什么添加 'self' 让我的代码工作,也许任何人都可以阐明一下?我首先尝试使用 send()instance_eval 之类的东西,将这段代码作为一种方法(例如 my_hash.instance_eval(my_method))发送到实际的哈希,但我无法让它工作。

对于冗长的解释,我深表歉意,我希望我已经足够清楚,以便任何遇到同样困境的人都能理解。提前致谢。

在方法名称前添加 self. 使其成为 class 方法而不是实例方法。如果您不确定其中的区别,您应该查找它,因为它是正确定义和使用 classes 和方法的基础。

作为 class 方法,您可以将其用作:

my_hash = MyHash.format_hash_data(my_hash)

或者如果您在 class 的范围内,只需 my_hash = format_hash_data(my_hash),这就是为什么它在您的情况下使用 self. 前置(class 方法定义)。

如果你想将其定义为实例方法(为实例定义的方法),你可以这样使用它:

my_hash = my_hash.format_hash_data

并且定义将使用实例的隐式 self

def format_hash_data
  self.inject({}) do |hash, record|
    # each record has the following format => [["unit_name", "axis.slug"]=>average_value(float)]
    keys, value = record
    # now keys has ["unit_name", "axis.slug"] and values equals average_value
    hash[keys.first] ||= {}
    hash[keys.first][keys.last] = value.to_f
    hash
  end
end