有没有办法在Ruby中动态创建数组?例如,假设我想循环浏览一系列书籍作为用户的输入:
books = gets.chomp
用户输入:
"The Great Gatsby, Crime and Punishment, Dracula, Fahrenheit 451,
Pride and Prejudice, Sense and Sensibility, Slaughterhouse-Five,
The Adventures of Huckleberry Finn"
我把它变成一个数组:
books_array = books.split(", ")
现在,对于每本书的用户输入,我想用Ruby创建一个数组。伪代码:
x = 0
books_array.count.times do
x += 1
puts "Please input weekly sales of #{books_array[x]} separated by a comma."
weekly_sales = gets.chomp.split(",")
end
显然这不起作用。它会一遍又一遍地重新定义weekly_sales
。有没有办法实现我所追求的目标,并且.times
方法的每个循环都会创建一个新数组?
答案 0 :(得分:7)
weekly_sales = {}
puts 'Please enter a list of books'
book_list = gets.chomp
books = book_list.split(',')
books.each do |book|
puts "Please input weekly sales of #{book} separated by a comma."
weekly_sales[book] = gets.chomp.split(',')
end
在ruby中,有一个哈希的概念,它是一个键/值对。在这种情况下,weekly_sales是哈希,我们使用书名作为键,数组作为值。
我对你的代码做了一个小改动,而不是使用books.count.times来定义循环,然后用计数器取消引用数组元素,每个都是迭代集合的更好方法。
答案 1 :(得分:2)
“push”命令会将项目附加到数组的末尾。
答案 2 :(得分:1)
您需要一种更强大的数据结构。
你的帖子倾向于认为weekly_sales
是一个与books
数组平行的数组。这种方法的缺点是你必须自己维护这两个数组的并行性。
一个更好的解决方案是使用书名作为数组哈希的关键,正如几个答案所暗示的那样。例如:weekly_sales['Fahrenheit 451']
将包含该图书的销售数据数组。这种方法取决于书籍标题的独特性,还有其他缺点。
您可能需要考虑的更强大的方法是将每本书的信息捆绑在一起。
最简单的一端是哈希列表。每本书都是这样一个独立的单元:
books = [
{
'title' => 'Fahrenheit 451',
'sales' => [1,2,3],
},
{
'title' => 'Slaughterhouse-Five',
'sales' => [123,456],
},
]
puts books[1]['title']
另一方面是创建一个合适的Book
类。
中间方法是使用Struct
(或OpenStruct
),它在哈希和完整对象之间占据中间地带。例如:
# Define the attributes that a Book will have.
Book = Struct.new(:title, :weekly_sales)
books = []
# Simulate some user input.
books_raw_input = "Fahrenheit 451,Slaughterhouse-Five\n"
sales_raw_input = ['1,2,3', '44,55,66,77']
books_raw_input.chomp.split(',').each do |t|
ws = sales_raw_input.shift.split(",")
# Create a new Book.
books.push Book.new(t, ws)
end
# Now each book is a handy bundle of information.
books.each do |b|
puts b.title
puts b.weekly_sales.join(', ')
end
答案 3 :(得分:0)
您是否乐意最终获得阵列数组?这可能是有用的:
book_sales = books_array.collect do |book|
puts "Please input weekly sales of #{books_array[0]} separated by a comma."
gets.chomp.split(",").collect{ |s| s.to_i }
end
看着它,你可能更喜欢用书键入的哈希。像这样:
book_sales = books_array.inject({}) do |hash, book|
puts "Please input weekly sales of #{books_array[0]} separated by a comma."
weekly_sales = gets.chomp.split(",").collect{ |s| s.to_i }
hash[book] = weekly_sales
end
答案 4 :(得分:0)
此解决方案假定永远不会有重复的书名。我觉得这很安全,是吗?
input = "A list of words"
hash = {}
input.split(/\s+/).collect { |word| hash[word] = [] }
# Now do whatever with each entry
hash.each do |word,ary|
ary << ...
end
答案 5 :(得分:0)
result = "The Great Gatsby, Crime and Punishment, Dracula, Fahrenheit 451,
Pride and Prejudice, Sense and Sensibility, Slaughterhouse-Five,
The Adventures of Huckleberry Finn".split(/,\s*/).map do |b|
puts "Please input weekly sales of #{b} separated by a comma."
gets.chomp.split(',') # .map { |e| e.to_i }
end
p result
如果您希望将输入字符串转换为数字
,请删除注释