计算数组中的几个元素

时间:2014-12-17 10:25:57

标签: ruby-on-rails ruby arrays loops

我刚写了一个方法,我很确定写得非常好。我无法弄清楚是否有更好的方法在ruby中写这个。这只是一个简单的循环计数。

当然,我可以使用select或类似的东西,但这需要在我的数组上循环两次。有没有办法通过循环增加几个变量而不在循环之前声明字段?有点像多重选择,我不知道。当我有更多的柜台时,情况甚至更糟。

谢谢!

failed_tests = 0
passed_tests = 0
tests.each do |test|
  case test.status
  when :failed
    failed_tests += 1
  when :passed
    passed_tests +=1
  end
end

5 个答案:

答案 0 :(得分:2)

你可以做一些聪明的事情:

tests.each_with_object(failed: 0, passed: 0) do |test, memo|
  memo[test.status] += 1
end
# => { failed: 1, passed: 10 }

答案 1 :(得分:2)

您可以使用#reduce方法:

failed, passed = tests.reduce([0, 0]) do |(failed, passed), test|
  case test.status
  when :failed
    [failed + 1, passed]
  when :passed
    [failed, passed + 1]
  else
    [failed, passed]
  end
end

或者Hash具有默认值,这适用于任何状态:

tests.reduce(Hash.new(0)) do |counter, test|
  counter[test.status] += 1
  counter
end

甚至用@ fivedigit的想法来增强这一点:

tests.each_with_object(Hash.new(0)) do |test, counter|
  counter[test.status] += 1
end

答案 2 :(得分:1)

假设Rails 4(这里使用4.0.x)。我建议:

tests.group(:status).count
# -> {'passed' => 2, 'failed' => 34, 'anyotherstatus' => 12}

这将按所有可能的:status值对所有记录进行分组,并计算每个单独的事件。

编辑:添加无Rails方法

Hash[tests.group_by(&:status).map{|k,v| [k,v.size]}]
  1. 按每个元素的值分组。
  2. 将分组映射到 [value,counter] 对的数组。
  3. 将巴黎数组转换为哈希中的键值,即可通过result[1]=2 ...访问。

答案 3 :(得分:1)

hash = test.reduce(Hash.new(0)) { |hash,element| hash[element.status] += 1; hash }

这将返回带有元素计数的哈希值。 例如:

class Test
  attr_reader :status

  def initialize
    @status = ['pass', 'failed'].sample
  end
end

array = []
5.times { array.push Test.new }

hash = array.reduce(Hash.new(0)) { |hash,element| hash[element.status] += 1; hash }
  

=> {“failed”=> 3,“pass”=> 2}

答案 4 :(得分:-1)

res_array = tests.map{|test| test.status}
failed_tests = res_array.count :failed
passed_tests = res_array.count :passed