Руби-хэш-свопинг значений с одного ключа на другой - PullRequest
1 голос
/ 04 августа 2011

Есть ли у кого-нибудь совет Ruby о том, как мне переопределить значения в хеше для разных ключей? Скажи, что у меня есть

from => {"first"=>30, "wanted"=>27, "second"=>45, "subject"=>68, "present"=>85} 

и хотел получить это (т. Е. Значения для «настоящего», «первого» и «субъекта», «второго» были изменены):

to => {"first"=>85, "wanted"=>27, "second"=>68, "subject"=>45, "present"=>30}

Я хочу сделать это для большого набора данных.

Ответы [ 5 ]

3 голосов
/ 04 августа 2011
# this is your starting hash:
from = {"first"=>30, "wanted"=>27, "second"=>45, "subject"=>68, "present"=>85}
# this is your replacement mapping:
map = {'present' => 'first', 'subject' => 'second'}
# create complete map by inverting and merging back
map.merge!(map.invert)
# => {"present"=>"first", "subject"=>"second", "first"=>"present", "second"=>"subject"} 
# apply the mapping to the source hash:
from.merge(map){|_, _, key| from[key]}
# => {"first"=>85, "wanted"=>27, "second"=>68, "subject"=>45, "present"=>30}
2 голосов
/ 04 августа 2011

Вы не предоставляете достаточно контекста, но вы можете сделать что-то вроде

 to = Hash[from.keys.zip(from.values_rearranged_in_any_way_you_like)]

Редактировать: from.values_rearranged_in_any_way_you_like должно быть from.values отсортировано так, как вам нужно (я полагаю, выдействительно есть желаемый способ сортировки их для перестановки).

0 голосов
/ 04 августа 2011

Проще говоря, используйте объединение:

from => {"first"=>30, "wanted"=>27, "second"=>45, "subject"=>68, "present"=>85}
to => {"first"=>85, "wanted"=>27, "second"=>68, "subject"=>45, "present"=>30}

from.merge(to)
# => {"first"=>85, "wanted"=>27, "second"=>68, "subject"=>45, "present"=>30}

Не уверен, что вам следует переопределять огромные хэши в ruby.

0 голосов
/ 04 августа 2011

Ну, вот простой маленький алгоритм. Я не знаю, насколько это будет эффективно, но это должно сработать.

class Hash
    def swap_vals!(new_key_maps)
        new_key_maps.each do |key1, key2|
            temp = self[key1]
            self[key1] = self[key2]
            self[key2] = temp
        end
    end
end
0 голосов
/ 04 августа 2011

Вы можете сделать что-то вроде этого:

keys = @hash.keys
values = @hash.values

, тогда вы можете поменять местами записи массива 'values' (или массива 'keys')

values[0], values[4] = values[4], values[0]

...

или если вы хотите сместить их только на один элемент:

values.rotate (ruby 1.9)

, вы также можете выполнить операции push / pop, shift / unshift или отсортировать значения. Чтобы создать хэш, выполните:

hsh = Hash.new
keys.size.times do |i|
  hsh[ keys[i] ] = values[i]
end
...