我知道|| =运算符,但不认为它会帮助我...尝试创建一个数组来计算对象数组中“类型”的数量。
array.each do |c|
newarray[c.type] = newarray[c.type] ? newarray[c.type]+1 ? 0
end
有更优雅的方法吗?
答案 0 :(得分:15)
types = Hash.new(-1) # It feels like this should be 0, but to be
# equivalent to your example it needs to be -1
array.each do |c|
types[c.type] += 1
end
答案 1 :(得分:6)
如果索引不存在,请使用Array#fetch
方法为其提供默认值:
array.each do |c|
newarray[c.type] = newarray.fetch(c.type, -1) + 1
end
答案 2 :(得分:4)
array.each do |c|
newarray[c.type] = 1 + (newarray[c.type] || -1)
end
可选地
array.each do |c|
newarray[c.type] ||= -1
newarray[c.type] += 1
end
答案 3 :(得分:2)
||=
确实有帮助:
types = {}
array.each do |c|
types[c.class] ||= 0
types[c.class] += 1
end
答案 4 :(得分:0)
您的变量newarray
名称很奇怪,因为在Ruby和大多数其他语言中,数组是由整数索引的,而不是像Class
这样的随机对象。这更有可能是Hash
。
此外,您应该使用c.class
,而不是c.type
,这已被弃用。
最后,由于您正在创建Hash
,因此您可以像inject
那样使用:{/ p>
newarray = array.inject( {} ) do |h,c|
h[c.class] = h.key?(c.class) ? h[c.class]+1 : 0
h
end
或者,对于单行:
newarray = array.inject( {} ) { |h,c| h[c.class] = h.key?(c.class) ? h[c.class]+1 : 0 ; h }
如您所见,这会产生预期效果:
irb(main):001:0> array = [1, {}, 42, [], Object.new(), [1, 2, 3]]
=> [1, {}, 42, [], #<Object:0x287030>, [1, 2, 3]]
irb(main):002:0> newarray = array.inject( {} ) { |h,c| h[c.class] = h.key?(c.class) ? h[c.class]+1 : 0 ; h }
=> {Object=>0, Hash=>0, Array=>1, Fixnum=>1}
答案 5 :(得分:0)
在Ruby 1.8.7或更高版本中,您可以使用group_by
然后将每个元素列表转换为count - 1,并从map
返回的数组中创建一个哈希值。
Hash[array.group_by(&:class).map { |k,v| [k, v.size-1] }]