Какой наилучший способ в Ruby усреднить наборы в массиве? - PullRequest
2 голосов
/ 19 мая 2009

Учитывая следующий простой набор данных, каков наилучший способ усреднить значения для наборов 0 25 53 и 80.

  [["0", "148.5"],
   ["0", "146.5"],
   ["0", "148.6"],
   ["0", "202.3"],
   ["25", "145.7"],
   ["25", "145.5"],
   ["25", "147.4"],
   ["25", "147.3"],
   ["53", "150.4"],
   ["53", "147.6"],
   ["53", "147.8"],
   ["53", "215.4"],
   ["80", "150.4"],
   ["80", "149.4"],
   ["80", "148.0"],
   ["80", "149.9"]]

Ответы [ 2 ]

6 голосов
/ 19 мая 2009

С инъекцией все достаточно просто. Я часто реализую общий метод group_by в проектах, чтобы помочь с такими вещами.

Если данные большие и вопросы производительности, рассмотрите возможность использования цифровой библиотеки или базы данных, если это необходимо.

data = [ ... ]

groups = data.inject({}) do |hash, pair| 
  hash[pair.first] ||= []
  hash[pair.first] << pair.last.to_f
  hash
end

groups.inject({}) do |hash, pair| 
  hash[pair.first] = pair.last.inject(0,&:+) / pair.last.size
  hash
end
1 голос
/ 25 мая 2009

Использование inject с хешем приведет к низкой производительности (вы переопределяете memo-переменную на каждой итерации). Если вы используете 1.9, Enumerable реализует метод group_by, который можно использовать, чтобы сделать код немного более очевидным:

result = array.map{ |row| [row.first.to_i, row.last.to_f] }.group_by(&:first)
result.each_pair do |key, values|
  result[key] = values.average
end

Array#average легко реализуется как

class Array
  def average
    inject(0.0) { |sum, e| sum + e } / length
  end
end

Тот факт, что ваши данные являются строками, довольно неудобен, я рекомендую избегать этого при любой возможности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...