如何在ruby中制作动态多维数组?

5 ruby arrays multidimensional-array

我有一个关于多维数组的初学红宝石问题.

我想按年份和月份对条目进行排序.所以我想创建一个包含年 - >月 - >月份条目的多维数组

所以数组就像:

2009 ->
       08
          -> Entry 1
          -> Entry 2
       09
          -> Entry 3
2007 ->
       10
          -> Entry 5
Run Code Online (Sandbox Code Playgroud)

我现在有:

@years = []
@entries.each do |entry|
    timeobj = Time.parse(entry.created_at.to_s)
    year = timeobj.strftime("%Y").to_i
    month = timeobj.strftime("%m").to_i
    tmparr = []
    tmparr << {month=>entry}
    @years.push(year)
    @years << tmparr
end
Run Code Online (Sandbox Code Playgroud)

但是当我尝试遍历岁月数组时,我得到:"未定义的方法`每个'为2009:Fixnum"

也尝试过:

@years = []
@entries.each do |entry|
    timeobj = Time.parse(entry.created_at.to_s)
    year = timeobj.strftime("%Y").to_i
    month = timeobj.strftime("%m").to_i
    @years[year][month] << entry
end
Run Code Online (Sandbox Code Playgroud)

Sin*_*our 10

您收到错误是因为FixNum在读取的行中将数字(即数字)推送到数组上@years.push(year).

你使用Arrays开始的方法有点缺陷; 数组非常适合保存有序的项目列表.在您的情况下,您有从键到值的映射,这对于哈希来说是完美的.

在第一级,键是年,值是哈希值.第二级的哈希包含月份的键和条目数组的值.

在这种情况下,代码的典型输出看起来像(基于您的示例):

{ 2009 => { 8 => [Entry1, Entry2], 9 => [Entry3] }, 2007 => { 10 => [Entry5] }}
Run Code Online (Sandbox Code Playgroud)

但请注意,年和月的顺序不保证按任何特定顺序排列.解决方案通常是在您想要访问它们时订购密钥.现在,一个代码,将产生这样的输出(根据您的代码布局,虽然可以取得多大rubier):

@years = {}
@entries.each do |entry|
  timeobj = Time.parse(entry.created_at.to_s)
  year = timeobj.strftime("%Y").to_i
  month = timeobj.strftime("%m").to_i
  @years[year] ||= {} # Create a sub-hash unless it already exists
  @years[year][month] ||= []
  @years[year][month] << entry
end
Run Code Online (Sandbox Code Playgroud)


Mic*_*cot 7

您可以使用group_bys和map:的组合将嵌套数组结构放在一行中:

@entries.group_by {|entry| entry.created_at.year }.map { |year, entries| [year, entries.group_by {|entry| entry.created_at.month }] }
Run Code Online (Sandbox Code Playgroud)