首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails:一个更简单的Hash.slice方法?

问Rails:一个更简单的Hash.slice方法?
EN

Stack Overflow用户
提问于 2015-07-09 02:51:33
回答 3查看 3.3K关注 0票数 3

在http://api.rubyonrails.org/classes/Hash.html#method-i-slice,我看到了

代码语言:javascript
复制
valid_keys = [:mass, :velocity, :time]
search(options.slice(*valid_keys))

我不懂这里的用法。我的意思是,如果我将一个array传递到slice中,我肯定希望每个key都被切片,那么为什么在这里使用一个附加的*呢?

是有可能使它成为这样的东西:

代码语言:javascript
复制
valid_keys = [:mass, :velocity, :time]
search(options.simple_slice(valid_keys))

通过创建一个更简单的slice版本

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-07-09 03:27:32

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

代码语言:javascript
复制
{ [ :mass, :velocity, :time ] => 'pancakes' }

Hash#slice怎么会知道有时这样:

代码语言:javascript
复制
h.slice([:mass, :velocity, :time])

意思是“给我这三个键的子散列”,有时它的意思是“给我带数组作为键的子散列”?

Hash#slice接受一个键列表(每个参数一个键),因此如果您想要将键放在数组中,那么您必须将它们分割成单独的参数:

代码语言:javascript
复制
h.slice(*some_array_of_keys)
# ------^ expand the array into individual arguments

这就是你需要*的原因。

如果您想假设键永远不会是数组,那么您可以自由地说这样的话:

代码语言:javascript
复制
def simple_slice(*keys) # Allow any number of arguments
  slice(*keys.flatten)  # flatten all the arrays and then punt to Rails's slice.
end

您可能不想只平平一个级别(也可能不想)。

票数 10
EN

Stack Overflow用户

发布于 2015-07-09 03:17:27

一切皆有可能。

下面是Hash#slice的原始源代码,如从你的问题链接所示

代码语言:javascript
复制
def 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

下面是你如何做这件事来挽救自己的键盘敲击。

代码语言:javascript
复制
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

然而,这样的simple_slice显然不那么灵活:原始切片允许将任意数量的键作为单独的参数传递,例如,除了一个抛出的数组options.slice(*valid_keys)之外,options.slice(:mass, :velocity, :time)还支持任意数量的键,但是simple_slice只支持数组。

票数 2
EN

Stack Overflow用户

发布于 2015-07-09 03:26:48

您需要拆分一个作为参数传递给#slice的数组,因为您需要弄清楚数组是包含所需键的列表还是是所需的键。几乎任何东西,包括数组,都可以是红宝石中的哈希键。

代码语言:javascript
复制
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运算符将数组分解为多个参数,而不是使用它作为单个array参数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31307300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档