Ruby:如何将变量设置为0,或者如果已经设置,则增加1

我知道|| =运算符,但不认为它会帮助我…尝试创建一个数组来计算对象数组中“类型”的数量。

array.each do |c| newarray[c.type] = newarray[c.type] ? newarray[c.type]+1 ? 0 end 

有没有更优雅的方式来做到这一点?

 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 

如果索引不存在,请使用Array#fetch方法为其提供默认值:

 array.each do |c| newarray[c.type] = newarray.fetch(c.type, -1) + 1 end 
 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 

||=有帮助:

 types = {} array.each do |c| types[c.class] ||= 0 types[c.class] += 1 end 

您的变量newarray名称很奇怪,因为在Ruby和大多数其他语言中,数组是由整数索引的,而不是像Class这样的随机对象。 这更像是一个Hash

此外,您应该使用c.class而不是不推荐使用的c.type

最后,既然你正在创建一个Hash ,你可以像这样使用inject

 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, [], #, [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} 

在Ruby 1.8.7或更高版本中,您可以使用group_by ,然后将每个元素列表转换为count – 1,并从map返回的数组中创建一个哈希。

 Hash[array.group_by(&:class).map { |k,v| [k, v.size-1] }]