1

I have a hash where the keys are the months and I want to convert the objects to positive numbers AND currency.

INPUT

hash = {
  12 => -5888.969999999999,
  4 => -6346.1,
  3 => -6081.76,
  2 => -5774.799999999999,
  1 => -4454.38
}

OUTPUT

hash = {
    12 => 5888.96,
    4 => 6346.10,
    3 => 6081.76,
    2 => 5774.79,
    1 => 4454.38
}

#Output should be a float

Any help would be greatly appreciated.

Lukas Baliak
  • 2,849
  • 2
  • 23
  • 26
SupremeA
  • 1,519
  • 3
  • 26
  • 43
  • expected output please – Arup Rakshit Jun 09 '15 at 20:10
  • Your output is invalid syntax - are the values strings or BigDecimals or what? – Anthony Jun 09 '15 at 20:22
  • 1
    Numeric.abs() can be applied to ensure a number is positive and Float.round(2) will round a float to 2 decimal places. See http://ruby-doc.org/core-2.1.4/Numeric.html#method-i-abs and http://ruby-doc.org/core-2.2.2/Float.html#method-i-round for usage examples. –  Jun 09 '15 at 20:25
  • So the abs method worked but I cant use float because some of the objects have 1 digit after decimal already and that throws an error – SupremeA Jun 09 '15 at 20:31
  • I updated the question for the output to be a float – SupremeA Jun 09 '15 at 20:40
  • @TrisNefzger That got it, with a little manipulation. Post an answer so I can give you credit. – SupremeA Jun 09 '15 at 21:53
  • @SupremeA - round() does not add trailing zeros since that does not affect numerical value. There is a trick of multiplying the number by 100 before rounding it and dividing by 100 afterwards when using plain round() with no precision argument - which still does not add trailing zeros. However, for printouts the number can be formatted to have a certain number of digits after the decimal point and which will be filled in with trailing zeros as needed. An example of how to do that is in my answer below. –  Jun 11 '15 at 00:03

2 Answers2

2

Try

hash.transform_values{|v| v.round(2).abs()}

or

hash.update(hash){|k,v| v.round(2).abs()}
Darpa
  • 396
  • 1
  • 8
  • 'An error' is unhelpful to people who are trying to help diagnose -- what is the error. – Mike Manfrin Jun 09 '15 at 20:52
  • NoMethodError: undefined method `transform_values' for # Bcs transform_values is ROR method so if you dont use ROR you must find another solution – Lukas Baliak Jun 09 '15 at 21:45
0

Numeric.abs() can be applied to ensure a number is positive and Float.round(2) will round a float to 2 decimal places. See ruby-doc.org/core-2.1.4/Numeric.html#method-i-abs and ruby-doc.org/core-2.2.2/Float.html#method-i-round for usage examples. Note that round() will not add trailing zeros since that does not affect numerical value, however trailing zeros can be added by formatting, for example:

hash = {
  12 => -5888.969999999999,
  4 => -6346.1,
  3 => -6081.76,
  2 => -5774.799999999999,
  1 => -4454.38
}

# transform hash values
hash.each do |key, value|
  hash[key] = value.abs().round(2)
end

# print the modified hash without formatting the values
hash.each do |key, value|
  puts "#{key} => #{value}"
end

# prints 
# 12 => 5888.97
# 4 => 6346.1
# 3 => 6081.76
# 2 => 5774.80
# 1 => 4454.38

# print hash with values formatted with precision of 2 digits
hash.each do |key, value|
  puts "#{key} => #{'%.2f' % value}"
end

# prints
# 12 => 5888.97
# 4 => 6346.10
# 3 => 6081.76
# 2 => 5774.80
# 1 => 4454.38
  • I am finding that `.round(2)` still can have an output such as `84.0`. June 5 2018, `Ruby 2.5.1`. – Rich_F Jul 05 '18 at 14:04