使用输入来确定要调用的数组

时间:2022-05-27 23:29:16

I'm still getting the basics of Ruby, and just completed an assignment to recreate the Tower of Hanoi. I would REALLY like to condense my code, but for that, I would need to call upon a specific array based on the users input. For example:

我仍然掌握了Ruby的基础知识,并完成了重建河内塔的任务。我真的想缩小我的代码,但为此,我需要根据用户输入调用特定的数组。例如:

 Stack_1=[5,4,3] 
 Stack_2=[5,2,1] 
 Stack_3=[5]

 puts "Please select a tower" 
 tower_select=gets.chomp.to_i
 puts "Please select where you'd like to move" 
 tower_move=gets.chomp.to_i

 if Stack_{tower_select}[-1] < Stack_{tower_move}[-1]   
   Stack_{tower_move} << Stack_{tower_select}[-1]   
   Stack_{tower_select}.delete_at(-1) 
 else puts "ERROR: Invalid move"
 end

Is this possible?

这可能吗?

2 个解决方案

#1


1  

Put your stacks in an Array or Hash and everything gets easier. This uses a Hash (they look scary at first, but are a breeze to handle):

将您的堆栈放在Array或Hash中,一切都变得更容易。这使用了哈希(它们起初看起来很吓人,但是处理起来很轻松):

stacks = {1 => [5,4,3],
          2 => [5,2,1],
          3 => [5]}  # a Hash

 puts "Please select a tower" 
 tower_select = gets.chomp.to_i
 puts "Please select where you'd like to move" 
 tower_move = gets.chomp.to_i

 if stacks[tower_select][-1] < stacks[tower_move][-1]   
   stacks[tower_move] << stacks[tower_select][-1]   
   stacks[tower_select].delete_at(-1)
   #or just: stacks[tower_move] << stacks[tower_select].pop 
 else puts "ERROR: Invalid move"
 end

p stacks

#2


1  

Yes, it is possible using Ruby's reflection methods:

是的,可以使用Ruby的反射方法:

 if const_get(:"Stack_#{tower_select}")[-1] < const_get(:"Stack_#{tower_move}")[-1]   
   const_get(:"Stack_#{tower_move}") << const_get(:"Stack_#{tower_select}")[-1]   
   const_get(:"Stack_#{tower_select}").delete_at(-1) 
 else
   puts 'ERROR: Invalid move'
 end

But you do not want to do this. Seriously. Don't. Just … don't.

但你不想这样做。认真。别。只是......不要。

Whenever you feel the need to have variables (or in this case constants, but it doesn't matter) named like foo_1, foo_2, etc. there is a better solution. You know, Ruby already has a data structure that you can put things into that you want to access by index. They are called arrays, and you already know about them since you actually use them in your code already:

无论什么时候你觉得需要变量(或者在这种情况下常量,但没关系),如foo_1,foo_2等,有一个更好的解决方案。你知道,Ruby已经有了一个数据结构,你可以把它放到你想要通过索引访问的内容中。它们被称为数组,您已经了解它们,因为您已经在代码中实际使用它们了:

stacks = [[5, 4, 3], [5, 2, 1], [5]]

puts 'Please select a tower'
tower_select = gets.to_i - 1 # somehow, "normal" humans count from 1 …
puts "Please select where you'd like to move" 
tower_move = gets.to_i - 1

if stacks[tower_select].last < stacks[tower_move].last   
  stacks[tower_move] << stacks[tower_select].pop   
else
  puts 'ERROR: Invalid move'
end

[You might notice a couple of additional fixes I put in there. Your code wasn't wrong, but this is more idiomatic.]

[您可能会注意到我在其中添加了一些其他修补程序。你的代码没有错,但这更加惯用。]

#1


1  

Put your stacks in an Array or Hash and everything gets easier. This uses a Hash (they look scary at first, but are a breeze to handle):

将您的堆栈放在Array或Hash中,一切都变得更容易。这使用了哈希(它们起初看起来很吓人,但是处理起来很轻松):

stacks = {1 => [5,4,3],
          2 => [5,2,1],
          3 => [5]}  # a Hash

 puts "Please select a tower" 
 tower_select = gets.chomp.to_i
 puts "Please select where you'd like to move" 
 tower_move = gets.chomp.to_i

 if stacks[tower_select][-1] < stacks[tower_move][-1]   
   stacks[tower_move] << stacks[tower_select][-1]   
   stacks[tower_select].delete_at(-1)
   #or just: stacks[tower_move] << stacks[tower_select].pop 
 else puts "ERROR: Invalid move"
 end

p stacks

#2


1  

Yes, it is possible using Ruby's reflection methods:

是的,可以使用Ruby的反射方法:

 if const_get(:"Stack_#{tower_select}")[-1] < const_get(:"Stack_#{tower_move}")[-1]   
   const_get(:"Stack_#{tower_move}") << const_get(:"Stack_#{tower_select}")[-1]   
   const_get(:"Stack_#{tower_select}").delete_at(-1) 
 else
   puts 'ERROR: Invalid move'
 end

But you do not want to do this. Seriously. Don't. Just … don't.

但你不想这样做。认真。别。只是......不要。

Whenever you feel the need to have variables (or in this case constants, but it doesn't matter) named like foo_1, foo_2, etc. there is a better solution. You know, Ruby already has a data structure that you can put things into that you want to access by index. They are called arrays, and you already know about them since you actually use them in your code already:

无论什么时候你觉得需要变量(或者在这种情况下常量,但没关系),如foo_1,foo_2等,有一个更好的解决方案。你知道,Ruby已经有了一个数据结构,你可以把它放到你想要通过索引访问的内容中。它们被称为数组,您已经了解它们,因为您已经在代码中实际使用它们了:

stacks = [[5, 4, 3], [5, 2, 1], [5]]

puts 'Please select a tower'
tower_select = gets.to_i - 1 # somehow, "normal" humans count from 1 …
puts "Please select where you'd like to move" 
tower_move = gets.to_i - 1

if stacks[tower_select].last < stacks[tower_move].last   
  stacks[tower_move] << stacks[tower_select].pop   
else
  puts 'ERROR: Invalid move'
end

[You might notice a couple of additional fixes I put in there. Your code wasn't wrong, but this is more idiomatic.]

[您可能会注意到我在其中添加了一些其他修补程序。你的代码没有错,但这更加惯用。]