2014-11-13 6 views
1

Finding суммы массива хэш-значений в рубин бросает ошибкуНахождение суммы массива хэш-значений в рубиновый

parsed_response = [ 
    {"type"=>"trading", "currency"=>"btc", "amount"=>"1.19782496", "available"=>"1.19782496"}, 
    {"type"=>"trading", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"deposit", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"deposit", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"exchange", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"exchange", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"} 
] 

parsed_response.map { |h| h["available"].to_f }.sum 

Это выдает следующее сообщение об ошибке:

undefined method `sum' for [1.19782496, 0.0, 0.0, 0.0, 0.0, 0.0]:Array (NoMethodError) 

Как мне изменить мой код?

+2

Я не могу найти, где вы звоните 'sum'? –

+2

работает для меня: 'parsed_response.map {| h | h ["available"]. to_f} .sum => 1.19782496' – Surya

+1

Вы конвертировали их в float с to_f в свой код, но в ошибке это похоже, что у вас нет - они все еще являются строками (которые могут не суммируется). Эта ошибка определенно вызвана линией кода, которую вы задали в своем вопросе? –

ответ

0

Ваш вопрос непонятен.

при активной поддержке, sum должны быть определены:

require 'active_support/all' 
parsed_response = [{"type"=>"trading", "currency"=>"btc", "amount"=>"1.19782496", "available"=>"1.19782496"}, {"type"=>"trading", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, {"type"=>"deposit", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, {"type"=>"deposit", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, {"type"=>"exchange", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, {"type"=>"exchange", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}] 
parsed_response.map { |h| h["available"].to_f }.sum 
# => 1.19782496 

без активной поддержки, sum не определен, и вы должны использовать inject(:+) вместо:

parsed_response = [{"type"=>"trading", "currency"=>"btc", "amount"=>"1.19782496", "available"=>"1.19782496"}, {"type"=>"trading", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, {"type"=>"deposit", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, {"type"=>"deposit", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, {"type"=>"exchange", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, {"type"=>"exchange", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}] 
parsed_response.map { |h| h["available"].to_f }.inject(:+) 
# => 1.19782496 

Если вы забыли to_f Перекодировки как ваши ошибки предлагает, вы соедините все струны:

["1.19782496", "0.0", "0.0", "0.0", "0.0", "0.0"].inject(:+) 
# => 1.197824960.00.00.00.00.0 
+1

'sum' является частью [' Enumerable'] (http://apidock.com/rails/Enumerable/sum) в классах «Rails» и «Array» включает в себя «Enumerable» –

+0

в рельсах действительно ... не в рубине – ThomasSevestre

+0

укажите это в ответе. –

0

супер простой способ для достижения этой цели:

result = 0.0 
parsed_response.each do |item| 
    result += item["available"].to_f 
end 
1

Поскольку вы используете только Ruby. Вы можете попробовать это (как нет sum метод массива в Ruby):

parsed_response.inject(0){|sum, response| sum = sum+response['available'].to_f } 
#=> 1.19782496 

Если вы используете Rails, то он имеет sum метод Enumerable который включен Array, могут быть использованы следующим образом:

parsed_response.map { |h| h["available"].to_f }.sum #=> 1.19782496 
+1

Я предпочитаю первый, так как он избегает создания временного массива, созданного 'map'. +1 –

1

Enumerable#sum - метод, который не существует в ванильном рубине. Скорее, это расширение, загруженное как часть рамки разработки веб-разработки Ruby on Rails.

В ванильным Ruby, разумный заменитель Enumerable#reduce:

parsed_response = [ 
    {"type"=>"trading", "currency"=>"btc", "amount"=>"1.19782496", "available"=>"1.19782496"}, 
    {"type"=>"trading", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"deposit", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"deposit", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"exchange", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"exchange", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"} 
] 

parsed_response.map { |h| h["available"].to_f }.reduce(:+) 
#=> 1.19782496 
0

Это работает:

parsed_response = [ 
    {"type"=>"trading", "currency"=>"btc", "amount"=>"1.19782496", "available"=>"1.19782496"}, 
    {"type"=>"trading", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"deposit", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"deposit", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"exchange", "currency"=>"btc", "amount"=>"0.0", "available"=>"0.0"}, 
    {"type"=>"exchange", "currency"=>"usd", "amount"=>"0.0", "available"=>"0.0"} 
] 

parsed_response.collect { |a| a["available"].to_f }.inject(:+) 
#=> 1.19782496 
Смежные вопросы