如何从哈希中添加用户指定的值

时间:2016-01-19 18:00:07

标签: ruby

我正在尝试创建一个程序,该程序会从用户输入中获取一个字符串并返回“'值”'单词a=1b=2c=3等等"cab" = 6

不幸的是,我无法弄清楚如何分解用户输入变量并将其添加到一起:

print "Give us a word to calculate: "
word = gets.chomp
alphabet = Hash[
  "a" => 1, "b" => 2, "c" => 3,
  "d" => 4, "e" => 5, "f" => 6,
  "g" => 7, "h" => 8, "i" => 9,
  "j" => 10, "k" => 11, "l" => 12,
  "m" => 13, "n" => 14, "o" => 15,
  "p" => 16, "q" => 17, "r" => 18,
  "s" => 19, "t" => 20, "u" => 21,
  "v" => 22, "w" => 23, "x" => 24,
  "y" => 25, "z" => 26
]

value = word.split("")
puts "Your word, \'#{word}\' has a value of: #{value}"

2 个答案:

答案 0 :(得分:4)

您可以使用reduce方法添加每个字符的值。

value = word.split("")
sum = value.reduce(0) {|sum, char| alphabet[char] + sum }
puts "Your word, \'#{word}\' has a value of: #{sum}"
#=> Your word, 'cab' has a value of: 6

这里我们使用reduce(具有别名方法inject)将数组缩减为单个值。我们从0的初始值开始,并迭代遍历数组的每个元素 - 在块中,我们将给定char的数字等价物添加到sum到目前为止 - 并最终得到总和所有数值。

在评论中回答问题:

  

我唯一相关的后续问题,是否可以定义   使用范围的哈希?我知道我可以用(" a" .." z")定义它们   和(1..26)但我不知道是否有办法设置这两个   根据指数值或某些

等于彼此的范围

您可以使用Array#zip方法,该方法允许通过在与子数组相同的索引处配对元素来合并两个数组。随后,我们可以利用方法Array#to_h将任何2元素数组的数组转换为哈希值。

alphabet = ('a'..'z').zip(1..26).to_h

答案 1 :(得分:3)

我建议以下作为一个很好的Ruby方式:

base = 'a'.ord-1
"catsup".each_char.map { |c| c.ord - base }.reduce(:+)
  #=> 80

打破它:

d = 'a'.ord
  #=> 97 
base = d-1
  #=> 96 
e = "catsup".each_char.map { |c| c.ord - base }
  #=> [3, 1, 20, 19, 21, 16] 
e.reduce(:+)
  #=> 80 

让我们更仔细地看一下e的计算:

enum0 = "catsup".each_char
  #=> #<Enumerator: "catsup":each_char> 

注意:

enum0.map { |c| c.ord - base }
  #=> [3, 1, 20, 19, 21, 16] 

要查看将传递给enum0的枚举器map的元素,请将其转换为数组:

enum0.to_a
  #=> ["c", "a", "t", "s", "u", "p"] 

现在让我们写一下:

enum1 = enum0.map
  #=> #<Enumerator: #<Enumerator: "catsup":each_char>:map>

研究返回值。您可以将enum1视为“复合”枚举器。

enum1.to_a
  #=> ["c", "a", "t", "s", "u", "p"] 
enum1.each { |c| c.ord - base }
  #=> [3, 1, 20, 19, 21, 16] 

我们现在可以使用Enumerator#next提取enum的每个元素,将块变量c设置为该值并执行块计算:

c = enum1.next #=> "c" 
c.ord - base  #=> 99-96 = 3 

c = enum1.next #=> "a" 
c.ord - base  #=> 1

c = enum1.next #=> "t"
c.ord - base  #=> 20 

c = enum1.next #=> "s" 
c.ord - base  #=> 19 

c = enum1.next #=> "u" 
c.ord - base  #=> 21 

c = enum1.next #=> "p" 
c.ord - base  #=> 16 

c = enum1.next #=> StopIteration: iteration reached an end