代码之家  ›  专栏  ›  技术社区  ›  michaelmichael

在Ruby中动态创建数组

  •  4
  • michaelmichael  · 技术社区  · 16 年前

    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 方法创建一个新数组?

    6 回复  |  直到 16 年前
        1
  •  7
  •   Matt Briggs    16 年前
    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
  •  2
  •   Derek    16 年前
        3
  •  1
  •   FMc TLP    16 年前

    无论如何,您需要一个更强大的数据结构。

    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
    
        4
  •  0
  •   Mike Woodhouse    16 年前

    您是否愿意以数组结束?这可能有用:

    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
    
        5
  •  0
  •   ezpz    16 年前

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

    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
    
        6
  •  0
  •   DigitalRoss    16 年前
    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
    

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