Как сделать динамический многомерный массив в рубине?

Нажатия клавиш для большего количества визуальных людей:

  1. Вводят Командный режим:

  2. Escape Перемещаются к запуску области для расположения с отступом:
    h j k l

  3. Запускает блок:
    v

  4. Перемещаются до конца области для расположения с отступом:
    h j k l

  5. (дополнительно) Вводит количество уровней отступа, которые Вы хотите
    0.. 9

  6. Выполняют добавление отступа на блоке:
    >

5
задан Nakilon 8 May 2015 в 00:39
поделиться

4 ответа

Вы получаете сообщение об ошибке, потому что FixNum (то есть число) добавлено в array в строке, которая читает @ years.push (year) .

Ваш подход к использованию массивов для начала немного ошибочен; массив идеально подходит для хранения упорядоченного списка элементов. В вашем случае у вас есть отображение ключей в значения, которое идеально подходит для хэша.

На первом уровне ключи - это годы, значения - хеши. Хэши второго уровня содержат ключи месяцев и значения массивов записей.

В этом случае типичный вывод вашего кода будет выглядеть примерно так (на основе вашего примера):

{ 2009 => { 8 => [Entry1, Entry2], 9 => [Entry3] }, 2007 => { 10 => [Entry5] }}

Обратите внимание, что, однако, порядок лет и месяцев не гарантируется, что они будут в каком-либо определенном порядке. Решение обычно состоит в том, чтобы заказывать ключи всякий раз, когда вы хотите получить к ним доступ. Теперь код, который будет генерировать такой вывод (на основе вашего макета кода, хотя его можно сделать намного 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
10
ответ дан 18 December 2019 в 06:51
поделиться

Вы можете получить структуру вложенного массива в одну строку, используя комбинацию group_by s и map :

@entries.group_by {|entry| entry.created_at.year }.map { |year, entries| [year, entries.group_by {|entry| entry.created_at.month }] }
7
ответ дан 18 December 2019 в 06:51
поделиться

Я использую хэш таблицы вместо массивов, потому что я думаю, что здесь это имеет больше смысла. Однако вернуться к использованию массивов, если вы предпочитаете, довольно тривиально.

entries = [
    [2009, 8, 1],
    [2009, 8, 2],
    [2009, 9, 3],
    [2007, 10, 5]
]

years = Hash.new
entries.each { |e|
    year = e[0]
    month = e[1]
    entry = e[2]

    # Add to years array
    years[year] ||= Hash.new
    years[year][month] ||= Array.new
    years[year][month] << entry
}

puts years.inspect

Результат: {2007 => {10 => [5]}, 2009 => {8 => [1, 2], 9 => [3]}}

3
ответ дан 18 December 2019 в 06:51
поделиться
# create a hash of hashes of array
@years = Hash.new do |h,k|
  h[k] = Hash.new do |sh, sk|
    sh[sk] = []
  end
end

@entries.each do |entry|
  timeobj = Time.parse(entry.created_at.to_s)
  year = timeobj.year
  month = timeobj.month
  @years[year][month] << entry
end
3
ответ дан 18 December 2019 в 06:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: