2013-07-09 2 views
-7

У меня есть следующий код:Преобразовать массив хэш

class A 
end 

class B 
end 

a1 = A.new 
a2 = A.new 
b1 = B.new 
b2 = B.new 

array = [a1, a2, b1, b2] 
hash = {} 

array.each do |obj| 
    if hash[obj.class] = nil 
     hash[obj.class] = [] 
    else 
     hash[obj.class] << obj 
    end 
end 

Я хочу хэш равным

{ A => [a1,a2], B => [b1,b2] } 

, но это говорит мне, что я не могу использовать оператор <<.

+6

Эй Брух, что об использовании двух приравнивает вместо одного для вашего состояния. – oldergod

+0

В конечном итоге с {A => [a2], B => [b2]} – mikeglaz

+0

Если есть одна вещь, которую должен изучить каждый разработчик Ruby, это понимание и отладка ошибок «NoMethodError: undefined method for nil: NilClass». –

ответ

1

Я думаю Enumerable#group_by является то, что вы ищете:

# ... 

array = [a1, a2, b1, b2] 
hash = array.group_by(&:class) 
# => {A=>[#<A:0x0000000190dbb0>, #<A:0x000000018fa470>], 
#  B=>[#<B:0x000000018e5fe8>, #<B:0x000000018daa80>]} 

(И, как было отмечено в комментариях, ошибка, вы получаете, потому что вы устанавливаете hash[obj.class] в nil, когда вы имели в виду, чтобы тест для равенства с ==.)

+0

да, спасибо, мне нужно использовать ==, но я также не могу использовать group_by. Мне нужно сделать это с чем-то вроде того, что я написал. – mikeglaz

+0

@mikeglaz 'group_by' делает именно то, что вы ищете ... Почему вы не можете использовать его? Это домашнее задание? –

2

Подведем итоги.

if hash[obj.class] = nil 

↑ вы перезагружаете вашу пару каждый раз, когда ваше состояние работает из-за уникальными равно, что установить hash[obj.class] в nil вместо тестирования его nillity. Вместо этого используйте ==.
Затем вы делаете

array.each do |obj| 
    if hash[obj.class] == nil 
    hash[obj.class] = [] # if nil, initialize to new array 
    else      # but because of the else, you are not... 
    hash[obj.class] << obj # doing this so you don't register the first object of each class. 
    end 
end 

Заключение

array.each do |obj| 
    hash[obj.class] ||= [] # set hash[obj.class] to [] if nil (or false) 
    hash[obj.class] << obj 
end 
Смежные вопросы