我将如何编写一个case
语句来列出数组中的所有元素,允许用户选择一个,并对该元素进行处理?
我有一个数组:
array = [ 'a', 'b', 'c', 'd' ]
最终我希望它表现得像这样:
Choices:
1) a
2) b
3) c
4) d
Choice =>
在用户选择 3 之后,我将根据用户的选择进行处理。我可以很容易地在 bash 中做到这一点。
Ruby 没有像 shell 脚本语言那样的内置菜单。在做菜单时,我倾向于构建一个可能选项的哈希并对其进行操作:
def array_to_menu_hash arr
Hash[arr.each_with_index.map { |e, i| [i+1, e] }]
end
def print_menu menu_hash
puts 'Choices:'
menu_hash.each { |k,v| puts "#{k}) #{v}" }
puts
end
def get_user_menu_choice menu_hash
print 'Choice => '
number = STDIN.gets.strip.to_i
menu_hash.fetch(number, nil)
end
def show_menu menu_hash
print_menu menu_hash
get_user_menu_choice menu_hash
end
def user_menu_choice choice_array
until choice = show_menu(array_to_menu_hash(choice_array)); end
choice
end
array = %w{a b c d}
choice = user_menu_choice(array)
puts "User choice was #{choice}"
魔法发生在array_to_menu_hash
:
Hash的[]
方法将具有表单的数组转换[ [1, 2], [3, 4] ]
为哈希{1 => 2, 3 => 4}
。为了得到这个数组,我们首先调用each_with_index
原始的菜单选择数组。这将返回一个在迭代时发出 [element, index_number] 的 Enumerator。这个 Enumerator 有两个问题:第一个是 Hash[] 需要一个数组,而不是 Enumerator。第二个是 Enumerator 发出的数组中的元素顺序错误(我们需要 [index_number, element])。这两个问题都用#map
. 这将 Enumerator 从 each_with_index 转换为数组数组,并且赋予它的块允许我们更改结果。在这种情况下,我们将向从零开始的索引添加 1 并反转子数组的顺序。