Ruby on rails RubyonRails:更简单的Hash.slice方法?

Ruby on rails RubyonRails:更简单的Hash.slice方法?,ruby-on-rails,ruby,hash,Ruby On Rails,Ruby,Hash,我明白了 我不明白这里的用法。我的意思是,如果我将数组传递到切片,我肯定希望每个键都被切片,那么为什么要在这里使用附加的* 可以将其制作成如下内容: valid_keys = [:mass, :velocity, :time] search(options.simple_slice(valid_keys)) def simple_slice(*keys) # Allow any number of arguments slice(*keys.flatten) # flatten all

我明白了

我不明白这里的用法。我的意思是,如果我将
数组
传递到
切片
,我肯定希望每个
都被切片,那么为什么要在这里使用附加的
*

可以将其制作成如下内容:

valid_keys = [:mass, :velocity, :time]
search(options.simple_slice(valid_keys))
def simple_slice(*keys) # Allow any number of arguments
  slice(*keys.flatten)  # flatten all the arrays and then punt to Rails's slice.
end
通过创建一个更简单的
切片版本

任何事情都有可能

以下是
散列#切片
的原始源代码,如图所示:

下面是你如何避免击键的方法

def simple_slice(keys)
  keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
  keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
end
然而,显然,这样一个
简单的
切片灵活性较差:原始切片允许作为单个参数传递任意数量的键,例如
options.slice(:mass,:velocity,:time)
,以及一个飞溅的数组
options.slice(*valid\u keys)
,但是
简单片将只支持数组。

任何事情都有可能

以下是
散列#切片
的原始源代码,如图所示:

下面是你如何避免击键的方法

def simple_slice(keys)
  keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
  keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
end

然而,显然,这样一个
简单的
切片灵活性较差:原始切片允许作为单个参数传递任意数量的键,例如
options.slice(:mass,:velocity,:time)
,以及一个飞溅的数组
options.slice(*valid\u keys)
,但是
simple_slice
将只支持数组。

您需要将作为参数传递的数组放在#slice中,因为您需要清楚数组是否包含所需键的列表,或者是否为所需键。几乎任何东西,包括数组,都可以是ruby中的哈希键

h = { 1 => "one", 2 => "two", [1,2] => "I'm an array!" }
array = [1,2]
h.slice(array)  => {[1, 2]=>"I'm an array!"}
h.slice(1,2)    => {1=>"one", 2=>"two"}
h.slice(*array) => {1=>"one", 2=>"two"}

splat操作符将数组分解为多个参数,而不是单个数组参数。

您需要将作为参数传递的数组splat到#slice中,因为您需要清楚数组是否包含所需键的列表或是否为所需键。几乎任何东西,包括数组,都可以是ruby中的哈希键

h = { 1 => "one", 2 => "two", [1,2] => "I'm an array!" }
array = [1,2]
h.slice(array)  => {[1, 2]=>"I'm an array!"}
h.slice(1,2)    => {1=>"one", 2=>"two"}
h.slice(*array) => {1=>"one", 2=>"two"}

splat运算符将数组分解为多个参数,而不是将其用作单个数组参数。

哈希可以包含各种键,键不必只是字符串或符号。例如,这是一个完全有效的哈希:

{ [ :mass, :velocity, :time ] => 'pancakes' }
Hash#slice
怎么知道有时:

h.slice([:mass, :velocity, :time])
意思是“给我这三个键的子散列”,有时它的意思是“给我这个数组作为键的子散列”

Hash#slice
获取一个键列表(每个参数一个键),因此如果要将键放入数组中,则必须将它们放入各个参数中:

h.slice(*some_array_of_keys)
# ------^ expand the array into individual arguments
这就是为什么您需要
*

如果您想假设密钥永远不会是数组,那么您可以自由地说:

valid_keys = [:mass, :velocity, :time]
search(options.simple_slice(valid_keys))
def simple_slice(*keys) # Allow any number of arguments
  slice(*keys.flatten)  # flatten all the arrays and then punt to Rails's slice.
end

您可能不想只展平一个级别(或者您不想展平)。

哈希可以有各种各样的键,键不必只是字符串或符号。例如,这是一个完全有效的哈希:

{ [ :mass, :velocity, :time ] => 'pancakes' }
Hash#slice
怎么知道有时:

h.slice([:mass, :velocity, :time])
意思是“给我这三个键的子散列”,有时它的意思是“给我这个数组作为键的子散列”

Hash#slice
获取一个键列表(每个参数一个键),因此如果要将键放入数组中,则必须将它们放入各个参数中:

h.slice(*some_array_of_keys)
# ------^ expand the array into individual arguments
这就是为什么您需要
*

如果您想假设密钥永远不会是数组,那么您可以自由地说:

valid_keys = [:mass, :velocity, :time]
search(options.simple_slice(valid_keys))
def simple_slice(*keys) # Allow any number of arguments
  slice(*keys.flatten)  # flatten all the arrays and then punt to Rails's slice.
end

您可能不想只展平一个级别(或者您不想展平)。

对于此方法的参数,您的问题更多的是“为什么需要展平一个数组”吗?Ref:@vee,我确实读过源代码,尽管我不太懂。但是最主要的问题是我认为切片应该做一些肮脏的工作,我不确定这种想法是否正确。你的问题更多的是“为什么你需要为这个方法的参数设置一个数组”吗?Ref:@vee,我确实读过源代码,尽管我不太懂。但是主要的问题是我认为切片应该做些肮脏的工作,我不确定这种想法是否正确。我感觉你说的是数组。展平与数组是一样的?我糊涂了吗?当测试OP的问题时,这两种方法返回不同的结果。如果
simple_slice(*keys)
被声明为这样,那么它与Rails的
active_support/core\u ext/hash/slice.rb#slice
没有什么不同,不是吗?@vee:不,它们非常不同
展平
展平所有嵌套数组(如果有),
*数组
用于匹配
哈希切片
的可变行为。试试
{[1,2]=>3[4,5]=>6}.slice([1,2])
{[1,2]=>3[4,5]=>6}.slice(1,2)
你会看到区别。我感觉你说的
array.flatte
*array
是一样的?我糊涂了吗?当测试OP的问题时,这两种方法返回不同的结果。如果
simple_slice(*keys)
被声明为这样,那么它与Rails的
active_support/core\u ext/hash/slice.rb#slice
没有什么不同,不是吗?@vee:不,它们非常不同
展平
展平所有嵌套数组(如果有),
*数组
用于匹配
哈希切片
的可变行为。尝试
{[1,2]=>3[4,5]=>6}.slice([1,2])
{[1,2]=>3[4,5]=>6}.slice(1,2)
,您将看到差异。