将数组转换为哈希

时间:2013-07-09 01:24:02

标签: ruby

我有以下代码:

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] }

但它告诉我我不能使用<<运算符。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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,因为您打算使用==来测试相等性。)< / p>