Можно ли вставить новый элемент в середину хэша и переиндексировать его? - PullRequest
2 голосов
/ 01 февраля 2011

У меня есть это как хеш:

>> params[:payments]

{"0"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}
{"1"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}
{"2"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}

Можно ли создать новый хеш и вставить его в определенное место? Например, возьмем эту строку:

{"2"=>{":amount_paid"=>"1.00", ":date_paid"=>"1/1/2006"}}

Так что хеш теперь будет выглядеть так:

{"0"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}
{"1"=>{":amount_paid"=>"1.00", ":date_paid"=>"1/1/2006"}}  # <-- Newly inserted line
{"2"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}
{"3"=>{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}}

Ответы [ 3 ]

4 голосов
/ 01 февраля 2011

Попробуйте использовать массив, так как хеши не упорядочены. Ruby Array.insert позволяет вам указать, куда вставить ваши новые объекты (http://www.ruby -doc.org / core / classes / Array.html # M000230), и, используя ваш пример выше, мы получим:

arr = [{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"},
{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"},
{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}]

arr.insert(2, {"some hash"}) 

[{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"},
{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"},
{"some hash"},
{":amount_paid"=>"100.00", ":date_paid"=>"2/20/2009"}]

Затем вы можете перебирать индексы и поддерживать желаемый порядок при добавлении к нему.

3 голосов
/ 01 февраля 2011

В Ruby 1.9+ хэши не упорядочены, вместо этого они поддерживают порядок вставки записей:

Из документов:

Хэши перечисляют свои значения в порядкечто соответствующие ключи были вставлены.

require 'pp'

hash = {
  'a' => 1,
  'c' => 3
}

hash['b'] = 2

pp hash
# >> {"a"=>1, "c"=>3, "b"=>2}

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

ruby-1.9.2-p136 :010 > Hash[*hash.sort.flatten]
 => {"a"=>1, "b"=>2, "c"=>3} 

Используйте это как:

hash = Hash[*hash.sort.flatten]

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

1 голос
/ 01 февраля 2011

Если вам нужно было сделать это с Hash, и вы не хотите использовать индекс массива, вы должны создать новый класс, OrderedHash.В этом классе необходимо создать метод insert и delete, который обеспечивает следующие свойства:

Вставка:

  1. новая запись имеет ключ, который находится в диапазоне(<= самый большой текущий ключ). </li>
  2. Если новая запись имеет ключ, который уже используется, для каждого числа от текущего нового значения ключа до наибольшего значения увеличивайте значение ключа на единицу.Вероятно, лучше всего делать это от самого большого до самого маленького, чтобы избежать проблем.
  3. Вставить новую запись

Удалить: при удалении записи уменьшите значение ключа для всех ключей> значение удаления.

...