我正在尝试制作一个使用名称并将其添加到数组中的程序。诀窍是我需要将它们存储在嵌套数组中,因此我要求用户输入数字-这定义了组的数量。然后要求用户输入名称-然后需要对这些名称进行排序...
我正在研究条件,我认为它们还可以。 但是其余的我还是很困惑……我不太了解将它们发送到嵌套数组的意图。
groups = []
#enter the number of groups
puts "give me a number"
count = gets.to_i
while true do
puts 'Give me a name'
user_input = gets.chomp
groups.push(user_input)
groups.delete("stop")
if user_input == "stop"
puts "Give me a group number"
puts groups[gets.to_i]
#puts'es the names from that group
break
end
end
这似乎还没有达到一百万英里,但是我不确定我要去哪里。
count = 3
user_input = ["joe","sally","frank"]
groups = Array.new(count) {Array.new(user_input)}
任何帮助将不胜感激,对此非常新
答案 0 :(得分:2)
首先,您必须基于给定的数字创建嵌套数组:
puts 'Enter number of groups'
count = gets.to_i
groups = Array.new(count) { [] }
如果用户输入 3 ,则您将拥有一个包含其他3个数组的数组:
groups = Array.new(3) { [] }
#=> [[], [], []]
对Array.new
使用 block形式很重要,这样每个内部数组都是一个单独的实例。 (请参阅文档中的“常见问题”)
有了适当的嵌套结构,我们可以将名称附加到内部数组中。通过使用“计数器”变量i
并推送到group[i]
:
puts 'Enter names or "stop" when done'
i = 0 # start at 0
loop do
user_input = gets.chomp
break if user_input == 'stop'
groups[i].push(user_input)
if i < count - 1
i += 1 # increment
else
i = 0 # start over
end
end
或者-更优雅-通过cycle
:
puts 'Enter names or "stop" when done'
groups.cycle do |group|
user_input = gets.chomp
break if user_input == 'stop'
group.push(user_input)
end
答案 1 :(得分:0)
获得组数后,说
ngroups = 3
该代码将提示用户输入一系列名称,然后当用户没有其他名称可输入时,输入"stop"
。假设用户按照指示的顺序输入以下字符串:
"Lucy\n", "Hank\n", "Billy-Bob\n", "Trixie\n", "Veronica\n", "Roxy\n",
"Norm\n", "Herb\n", "stop\n"
我们可以使用以下代码创建所需的数组:
0.step.with_object(Array.new(ngroups) { [] }) do |i,a|
print 'Please enter a name or "stop" if finished: '
reply = gets.chomp
break a if reply == "stop"
a[i % ngroups] << reply
end
#=> [["Lucy", "Trixie", "Norm"], ["Hank", "Veronica", "Herb"],
# ["Billy-Bob", "Roxy"]]
请注意,我没有要求用户为每个名称输入一个组。那是因为您说过要按组顺序将名称分配给组,在将名称分配给最后一个组之后,将与第一个组重新开始。
对于任何不熟悉Ruby的人来说,这段代码看起来都相当复杂。但是,它非常像Ruby,并且任何最红宝石的人都会在学习了某种语言后立即理解它。让我分解步骤。有了耐心,您应该能够了解发生了什么。
Numeric#step,枚举器
enum0 = 0.step #=> (0.step)
如果您检查此方法的文档,您会发现0.step
不带任何块将返回一个枚举数,它是类Enumerator的一个实例。枚举器在Ruby中非常重要。它们生成可以传递给其他方法或阻塞的值。在这里,enum0
生成以下序列:
enum0.next #=> 0
enum0.next #=> 1
enum0.next #=> 2
... 无限地。参见Enumerator#next。
类似地,
e = 21.step(by: -3) #=> (21.step(by: -3))
e.next #=> 21
e.next #=> 18
e = 2.34.step #=> (2.34.step)
e.next #=> 2.34
e.next #=> 3.34
我们实际上不需要使用此方法。相反,我们可以编写以下代码,得到相同的结果:
a = []
0.step do |i|
print 'Please enter a name or "stop" if finished: '
reply = gets.chomp
break a if reply == "stop"
a[i % ngroups] << reply
end
a
如您所见,使用each_object
仅节省了两行代码:最后是a = []
和a
。 1 。实际上,这种方法及其表亲Enumerable#each_with_object非常简单。
另一个枚举器
接下来我们有:
enum1 = enum0.with_object(Array.new(ngroups) { [] })
#=> #<Enumerator: (0.step):with_object([[], [], []])>
从enum1
的返回值中可以看到,enum1
可以被视为复合枚举器,尽管Ruby没有这样的形式概念。让我们看看这个枚举器产生什么值:
enum1.next #=> [0, [[], [], []]]
enum1.next #=> [1, [[], [], []]]
enum1.next #=> [2, [[], [], []]]
您会看到,每个生成的值都是两个元素组成的数组,第一个是从零开始的计数器,第二个是由三组组成的数组。这些组现在为空,但是将在计算进行时将其填写。
如果希望的话,我们现在可以如下编写原始代码 1
enum1.each do |i,a|
print 'Please enter a name or "stop" if finished: '
reply = gets.chomp
break a if reply == "stop"
a[i % ngroups] << reply
end
请参见Enumerator#each。
将enum1
生成的元素传递到块
生成第一个元素并将其传递给块时,将为块变量i
和a
分配如下值:
i, a = enum1.next #=> [0, [[], [], []]]
i #=> 0
a #=> [[], [], []]
将enum1.next
返回的数组分解成其组件的过程称为array decomposition。这是一个强大而有价值的工具。
我们现在可以执行块操作了。
print 'Please enter a name or "stop" if finished: '
reply = "Lucy" # = gets.chomp
break a if reply == "stop" # do not break
a[i % ngroups] << reply
#=> a[0 % 3] << "Lucy"
#=> a[0] << "Lucy"
#=> ["Lucy"]
下一步enum1
生成第二个值并将其传递给块,将值分配给块变量并执行块操作。
i, a = enum1.next #=> [1, [["Lucy"], [], []]]
i #=> 1
a #=> [["Lucy"], [], []]
请注意,a
已更新,以反映"Lucy"
已附加到a[0]
。继续
print 'Please enter a name or "stop" if finished: '
reply = "Hank" # = gets.chomp
break a if reply == "stop" # do not break
a[i % ngroups] << reply
#=> a[1 % 3] << "Hank"
#=> a[1] << "Hank"
#=> ["Hank"]
现在
a #=> => [["Lucy"], ["Hank"], []]
其余计算类似。
1。在运行以下命令之前,我需要执行enum1.rewind
重新初始化枚举数。参见Enumerator#rewind。