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

但是我怎样才能写得更简洁和动态呢?

4

4 回答 4

4

我会按功能使用分组:

 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]

不带 group_by 的备选方案 2:

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]
于 2013-10-19T21:06:22.140 回答
1

你可以这样做,但你发现只使用 hash 更有用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)

谢谢,维克多,一个明确的改进(除非使用哈希就足够了)。

于 2013-10-19T22:25:03.410 回答
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 
于 2013-10-19T20:52:50.767 回答
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"]
于 2013-10-19T21:06:22.380 回答