Получить среднее число чисел в массиве, которое является значениями хеша - PullRequest
0 голосов
/ 19 октября 2019

в программе на Ruby у меня есть хеш, в котором ключами являются нормальные строки, а значения - это массив чисел:

hash_1 = {"Luke"=> [2,3,4], "Mark"=>[3,5], "Jack"=>[2]}

И в результате я получаю такой же хеш сзначения, которые становятся средними числами внутри массивов:

{"Luke"=> 3, "Mark"=>4, "Jack"=>2}

Один из способов заставить его работать - это создать новый пустой hash_2, перебрать hash_1 и в пределах блока назначить ключи hash_2. и среднее число чисел в виде значений.

hash_2 = {}

hash_1.each do |key, value|
  hash_2[key] = value.sum / value.count
end

hash_2 = {"Luke"=> 3, "Mark"=>4, "Jack"=>2}

Есть ли лучший способ, которым я мог бы сделать это, например, без необходимости создавать новый хэш?

Ответы [ 4 ]

4 голосов
/ 19 октября 2019
hash_1 = {"Luke"=> [2,3,4], "Mark"=>[3,5], "Jack"=>[2]}

Вам не нужен еще один хеш для указанного ниже кода.

p hash_1.transform_values!{|x| x.sum/x.count}

Результат

{"Luke"=>3, "Mark"=>4, "Jack"=>2}
2 голосов
/ 20 октября 2019
def avg(arr)
  return nil if arr.empty?
  arr.sum.fdiv(arr.size)
end

h = { "Matthew"=>[2], "Mark"=>[3,6], "Luke"=>[2,3,4], "Jack"=>[] }

h.transform_values { |v| avg(v) }
  #=> {"Matthew"=>2.0, "Mark"=>4.5, "Luke"=>3.0, "Jack"=>nil}
0 голосов
/ 19 октября 2019

Это решение отличается от того, которое использует transform_values!, потому что возвращает новый объект Hash.

hash_1.map { |k,v| [k, v.sum / v.size] }.to_h
0 голосов
/ 19 октября 2019

@ Виктор ОК. Как насчет этого:

hash_1 = {"Luke"=> [2,3,4], "Mark"=>[3,5], "Jack"=>[2], "Bobby"=>[]}

hash_2 = hash_1.reduce(Hash.new(0)) do |acc, (k, v)|
  v.size > 0 ? acc[k] = v.sum / v.size : acc[k] = 0 
  acc
end

p hash_2
...