我有一个数组:
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
但是我怎么能把它写得更简洁和动态呢?
答案 0 :(得分:3)
我会按功能使用该组:
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]
答案 1 :(得分:1)
您可以这样做,但您发现仅使用哈希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]
编辑:正如@Victor建议的那样,最后两行可以替换为:
array.reduce(Hash.new(0)) {|h, e| h[e] += fac; h}.values_at(*array)
谢谢,Victor,一个明确的改进(除非使用哈希就足够了)。
答案 2 :(得分: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
答案 3 :(得分: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"]