2015-06-10 66 views
0

我想计算mysql表列中不同值的数量。可能值的范围是整数,从0到10。下面的代码正在工作,但我想知道是否有一个更优雅的方式来做到这一点?计算红宝石中值的出现

# Example data from Mysql 
result = [{ :column1 => "2", :column2 => "3", :column3 => "1"},{ :column1 => "2", :column2 => "3", :column3 => "1"},{ :column1 => "1", :column2 => "2", :column3 => "3"}] 

# Init hash 
final_result = Hash.new { |h, k| h[k] = { } } 

# Loop result columns 
result.each do |single_column| 

    # Loop single items inside columns 
    single_column.each do |single_result| 

      # Create column if does not exist 
      if final_result[single_result[0]][single_result[1]].nil? then 
       final_result[single_result[0]][single_result[1]] = 1 
      else 
       final_result[single_result[0]][single_result[1]] += 1 
      end 
    end 
end 

puts final_result 
# => {:column1=>{"2"=>2, "1"=>1}, :column2=>{"3"=>2, "2"=>1}, :column3=>{"1"=>2, "3"=>1}} 
+0

我不认为标题的变化是正确的,并投票反对它。通过使用MySQL来完成大部分工作,有一种更好的方式可以做到这一点。所以原来的标题是好的IMO。 – ReggieB

回答

1

这里有一些清理空间。最明显的部分就是那长而笨拙的if声明。测试VS nil?是没有意义的,记住Ruby中事情是逻辑假是falsenil,这样以来false是永远不会出现在这里,测试与nil具体可以去掉。

尽管如此,您还是可以通过自定义的Hash.new调用找到正确的方向,但是您不会走得太远。为什么不用零初始化第二层?

导致代码看起来像:

result = [ 
    { :column1 => "2", :column2 => "3", :column3 => "1"}, 
    { :column1 => "2", :column2 => "3", :column3 => "1"}, 
    { :column1 => "1", :column2 => "2", :column3 => "3"} 
] 

# Init hash 
final_result = Hash.new { |h, k| h[k] = Hash.new(0) } 

# Loop result columns 
result.each do |single_column| 
    single_column.each do |r| 
    final_result[r[0]][r[1]] += 1 
    end 
end 

puts final_result.inspect 
1

看一看活动记录count方法(doc link)。您可以结合使用group来完成您正在努力实现的目标。

[:column1, :column2, :column3].inject({}) do |hash, column| 
    hash[column] = Model.group(column).count 
    hash 
end