我正在尝试创建一个程序,该程序会从用户输入中获取一个字符串并返回“'值”'单词a=1
,b=2
,c=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}"
答案 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