为什么我无法编辑此散列中的值?

Why am I unable to edit the values in this hash?

我正在尝试创建一个名为 $player[:abil_mods] 的新哈希,它基于我的 $player[:abils] 哈希。它应该将每个值减去 10,除以 2,然后将其分配给新哈希中的相同键。但是,它似乎没有编辑 $player[:abil_mods].

中的值

我的代码:

$player = {
  abils: {str: 20, con: 20, dex: 14, wis: 12, int: 8, cha: 8},
  abil_mods: {}
}

$player[:abil_mods] = $player[:abils].each { |abil, pts| ((pts - 10) / 2).floor }

应该创建以下 $player[:abil_mods] 哈希:

abil_mods: {str: 5, con: 5, dex: 2, wis: 1, int: -1, cha: -1}

但它正在创建:

abil_mods: {str: 20, con: 20, dex: 14, wis: 12, int: 8, cha: 8}

只需在这一行中使用 map 而不是 each

$player[:abil_mods] = $player[:abils].map { |abil, pts| ((pts - 10) / 2).floor }

each 遍历数组,但 return 遍历原始数组。而 map return 是新值。

顺便说一句:使用全局变量(带有 $ 的变量)几乎每次都是一个坏主意。首选使用局部变量实例。

问题是在行

$player[:abil_mods] = $player[:abils].each { |abil, pts| ((pts - 10) / 2).floor }

您正在将方法 Hash#each 的 return 值 self 分配给键 :abil_mods 处的哈希 $player。在您的情况下,哈希由 $player[:abils].

引用

您可以使用 Enumerable#map,其中 return 是一个可以轻松转换为散列的数组:

$player[:abil_mods] = $player[:abils].map { |k, pts| [k,  ((pts - 10) / 2).floor] }.to_h

我很确定 #each returns 它正在运行的哈希。 (至少这就是它在数组上的工作方式...)更多的是 对每个条目做一些事情 而不是返回那件事的结果。

您可以试试:

$player[:abil_mods] = $player[:abils].transform_values { |pts| ((pts - 10) / 2).floor }