创建数据并将其输入嵌套数组-Ruby

时间:2019-05-08 11:25:38

标签: arrays ruby multidimensional-array

我正在尝试制作一个使用名称并将其添加到数组中的程序。诀窍是我需要将它们存储在嵌套数组中,因此我要求用户输入数字-这定义了组的数量。然后要求用户输入名称-然后需要对这些名称进行排序...

  • 例如,假设有三个组。
    • 第一人称进入第一组。
    • 第二个人进入第二组。
    • 第三人进入第三组。
    • 第四个人进入第一组。
    • 第五个人进入第二组。

我正在研究条件,我认为它们还可以。 但是其余的我还是很困惑……我不太了解将它们发送到嵌套数组的意图。

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)}

任何帮助将不胜感激,对此非常新

2 个答案:

答案 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 

Enumerator#with_object

我们实际上不需要使用此方法。相反,我们可以编写以下代码,得到相同的结果:

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生成的元素传递到块

生成第一个元素并将其传递给块时,将为块变量ia分配如下值:

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