【问题标题】:What is the ruby idiomatic way to set a hash entry to a array before appending to it? [duplicate]在附加到数组之前将哈希条目设置为数组的 ruby​​ 惯用方法是什么? [复制]
【发布时间】:2019-03-14 12:34:18
【问题描述】:

我正在尝试创建一个散列,其中包含一个键和一个与该键关联的值数组。 所以我在做这样的事情

 hash = Hash.new

然后当我有钥匙时,我会这样做

 hash[key] << new_thing

但如果 hash[key] 为 nil 则会失败,因此我在尝试将 new_thing 附加到数组之前添加了此语句。

 hash[key] = Array.new unless hash[key] 
 hash[key] << new_thing

我认为我可以通过将 hash 的定义更改为来消除添加的语句

hash = Hash.new Array.new 

但这不起作用,因为每个条目共享相同的数组,我真正需要的是这个

hash = Hash.new { |h,k| h[k] = Array.new }

我知道我可能正在分裂头发,但我只是好奇,“红宝石”方法是什么?

编辑: 最终我最终做的是使用 group_by。我意识到我的问题并不明显,我试图使用这种结构将具有相同属性的对象分组到一个散列中。我将其包括在内是为了鼓励其他可能发现自己出于类似目的使用类似结构的人查看group_by

["A", 1, "b", 3].group_by { |i| i.class }
=> {String=>["A", "b"], Fixnum=>[1, 3]}

【问题讨论】:

  • 你上一个default_proc 版本有什么问题?
  • 它有效,但我想我认为它可能比添加的语句更令人困惑。我认为这一定会出现很多,并且有一些首选的方法可以做到这一点
  • 什么是hash{key]?它甚至不是有效的 Ruby 代码。
  • @sawa:一个简单的错字?
  • @sawa:鉴于{[ 在键盘上的通常位置,很明显这是一个错字。也许如果您问hash{key] 是否是一个错字,您会得到更友好的回答。

标签: ruby hash


【解决方案1】:

将空数组设置为 Hash 的默认值的 Ruby 方法是使用您问题中的 default_proc 版本:

hash = Hash.new { |h,k| h[k] = [ ] }

例如:

> hash = Hash.new { |h,k| h[k] = [ ] }
> hash[:pancakes] << 6
> hash
 => {:pancakes=>[6]} 

在编写 Ruby 时使用标准 Ruby 功能对我来说似乎是 Rubyish。

【讨论】:

  • 使用 [ ] 代替 Array.new 更好 - 谢谢
  • 是的,您看到Array.new 的唯一时间是您需要向构造函数提供参数(Hash.new 也是如此)。
【解决方案2】:

我经常看到人们这样做:

(h[key] ||= []) << value

因为那是显式的方式,而rubists 喜欢显式。

不过你的版本也很常见。

顺便说一句,您可以在现有哈希上设置默认值:

h.default_proc = ->(h, k){ h[k] = [] }

h.default = 0

而且我发现它更干净一些,但没有被广泛使用。

【讨论】:

  • 嗯,那是误导。我会更新答案。
  • nPn,使用 Bartosz 的第一种方法的一个结果是 puts "hello" if h[7] 给出了预期的结果(只要 h 不包含 nil 值),而 h[7] 将始终是如果哈希是使用默认值创建的,则为 true,如果使用 Hash.new {|h,k| h[k] = []} 创建,则为 h =&gt; [7](在 h =&gt; {} 之后)。也许教训是始终使用Hash#key?(又名has_key?)来检查密钥是否存在。
【解决方案3】:

你可以设置default

numbers = Hash.new(0)

【讨论】:

    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 2010-09-07
    • 2013-11-07
    • 2021-01-27
    • 2010-12-11
    • 2018-01-28
    • 2013-06-26
    • 2018-11-28
    相关资源
    最近更新 更多