2013-10-19 37 views
0

我有一个数组:红宝石计算阵列的百分比对象

array = ["one", "two", "two", "three"]

现在我需要创建与每个这些项目的百分数单独阵列出总阵列的。

最终结果:

percentages_array = [".25",".50",".50",".25]

我可以做这样的事情:

percentage_array = [] 
one_count = array.grep(/one/).count 
two_count = array.grep(/two/).count 

array.each do |x| 
    if x == "one" 
    percentage_array << one_count.to_f/array.count.to_f 
    elsif x == "two" 
    .... 
    end 
end 

但我怎么能写多一点简洁和活力呢?

回答

3

我会使用GROUP BY功能:

my_array = ["one", "two", "two", "three"] 
percentages = Hash[array.group_by{|x|x}.map{|x, y| [x, 1.0*y.size/my_array.size]}] 
p percentages #=> {"one"=>0.25, "two"=>0.5, "three"=>0.25} 
final = array.map{|x| percentages[x]} 
p final #=> [0.25, 0.5, 0.5, 0.25] 

替代2无GROUP_BY:

array, result = ["one", "two", "two", "three"], Hash.new 
array.uniq.each do |number| 
    result[number] = array.count(number) 
end 
p array.map{|x| 1.0*result[x]/array.size} #=> [0.25, 0.5, 0.5, 0.25] 
+0

@SirDarius,它至少在1.9和2.0中可用。请检查文档:http://ruby-doc.org/core-2.0.0/Enumerable.html – hirolau

+0

是的,出于某种原因,我没有检查它们,并没有_see_方法,从来没有见过我的评论! – SirDarius

+0

这很好,'group_by'对我来说是一个新的。谢谢。 – Luigi

0
percentage_array = [] 
percents = [0.0, 0.0, 0.0] 
array.each do |x| 
    number = find_number(x) 
    percents[number] += 1.0/array.length 
end 
array.each do |x| 
    percentage_array.append(percents[find_number(x)].to_s) 
end 

def find_number(x) 
    if x == "two" 
    return 1 
    elsif x == "three" 
    return 2 
    end 
    return 0 
end 
0

下面是做到这一点的通用方式:

def percents(arr) 
    map = Hash.new(0) 
    arr.each { |val| map[val] += 1 } 
    arr.map { |val| (map[val]/arr.count.to_f).to_s } 
end 

p percents(["one", "two", "two", "three"]) # prints ["0.25", "0.5", "0.5", "0.25"] 
1

你可以做到这一点,但你觉得它更有用UL只使用哈希h

array = ["one", "two", "two", "three"] 

fac = 1.0/array.size 
h = array.reduce(Hash.new(0)) {|h, e| h[e] += fac; h} 
    # => {"one"=>0.25, "two"=>0.5, "three"=>0.25} 
array.map {|e| h[e]} # => [0.25, 0.5, 0.5, 0.25] 

编辑:

array.reduce(Hash.new(0)) {|h, e| h[e] += fac; h}.values_at(*array) 

谢谢,维克多,一个明确的改善(除非使用的:作为@Victor建议,最后两行可以替换为散列就足够了)。

+0

'h.values_at(* array )'因为最后一行看起来更好,可以链接到前一行 –