【问题标题】:Dynamically Create Arrays in Ruby在 Ruby 中动态创建数组
【发布时间】:2009-12-01 21:56:32
【问题描述】:

有没有办法在 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 方法的每个循环中创建一个新数组?

【问题讨论】:

  • 我认为你想要一个哈希,而不是一个数组。这样您就可以参考每本书(作为键)和书籍的每周销量作为价值。
  • 是的,这似乎是答案中的共识。

标签: ruby arrays hash


【解决方案1】:
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 来定义循环,然后使用计数器取消引用数组元素,每个都是迭代集合的更好方法。

【讨论】:

  • 这是有道理的。我知道必须有一种不同的方式来看待这个问题,而我并没有完全理解。这很有效,并且是构建脚本其他方面的良好基础。
【解决方案2】:

“push”命令会将项目追加到数组的末尾。

Ruby Docs->Array->push

【讨论】:

    【解决方案3】:
    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
    

    如果您想将输入字符串转换为数字,请删除注释

    【讨论】:

      【解决方案4】:

      您需要更强大的数据结构。

      您的帖子倾向于认为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
      

      【讨论】:

        【解决方案5】:

        您对得到一个数组数组感到高兴吗?这可能有用:

        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
        

        【讨论】:

          【解决方案6】:

          此解决方案假定永远不会有重复的书名。我认为这很安全,是吗?

          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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-03-29
            • 2011-04-02
            • 2012-05-27
            相关资源
            最近更新 更多