Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json Ruby输出数字到小数点后2位_Json_Ruby_Number Formatting - Fatal编程技术网

Json Ruby输出数字到小数点后2位

Json Ruby输出数字到小数点后2位,json,ruby,number-formatting,Json,Ruby,Number Formatting,我无法将ruby对象序列化为json,更确切地说是数字的格式。 我已经编写了一个rspec测试来更准确地说明我的问题 expected = '{ "foo": 1.00, "bar": 4.50, "abc": 0.00, "xyz": 1.23 }' it 'serializes as expected' do my_hash = { "foo": 1, "bar": 4.5, "abc": 0, "xyz": 1.23} expect(my_to_json_method(my_ha

我无法将ruby对象序列化为json,更确切地说是数字的格式。 我已经编写了一个rspec测试来更准确地说明我的问题

expected = '{ "foo": 1.00, "bar": 4.50, "abc": 0.00, "xyz": 1.23 }'

it 'serializes as expected' do
  my_hash = { "foo": 1, "bar": 4.5, "abc": 0, "xyz": 1.23}
  expect(my_to_json_method(my_hash)).to eq expected
end 
这就是我遇到的问题。我可以使用sprintf,但是如何获得上面示例中所示的字符串输出?

用户sprintf

sprintf('.2f',5.5)


只需在JSON中插入一个ERB模板。

您可以使用,
sprintf
,并可以通过提及
%。(number)f
获取所需的小数点

例如:对于两位小数,
%.2f

这是一个真正的实现

2.2.2 :019 > test = { "foo": (sprintf "%.2f","1.11"), "bar": (sprintf "%.2f","4.55"), "abc": (sprintf "%.2f","0.2") }

 => {:foo=>"1.11", :bar=>"4.55", :abc=>"0.20"}

放置“{”首先,您不应该使用浮点数来表示货币值。因此,让我们使用更合适的类型:(还有Ruby gem)

有几个选项可以表示货币值。根据JSON规范,以下所有JSON字符串都是有效的,并且在解析时都需要特殊处理。您可以选择最合适的字符串

注意:我正在实现一个自定义的
to_json
方法,使用Ruby的默认json库将
BigDecimal
实例转换为json。这只是为了演示,您通常不应该修补核心(或stdlib)类


1.具有固定精度的数字 请注意,许多JSON库在默认情况下会将这些数字解析为浮点值

class BigDecimal
  def to_json(*)
    '%.2f' % self
  end
end
puts my_hash.to_json
输出:

{“foo”:1.00,“bar”:4.50,“abc”:0.00,“xyz”:1.23}

2.数字作为字符串 这将适用于所有JSON库,但将数字存储为字符串在我看来并不太合适

class BigDecimal
  def to_json(*)
    '"%.2f"' % self
  end
end
puts my_hash.to_json
输出:

{“foo”:“1.00”,“bar”:“4.50”,“abc”:“0.00”,“xyz”:“1.23”}

3.作为整数的数字 你不需要用分数来表示货币价值,只需要把美分作为整数来输出,这是我通常做的

class BigDecimal
  def to_json(*)
    (self * 100).to_i.to_s
  end
end
puts my_hash.to_json
输出:

{“foo”:100,“bar”:450,“abc”:0,“xyz”:123}

请尝试这个,
test={“foo”:(sprintf“%.2f”,“1.0”),“bar”:(sprintf“%.2f”,“4.50”),“abc”:(sprintf“%.2f”,“0”)}
这些值的输出是字符串。因此,格式是有效的,但我希望结果不在结果中引用字符串。@mcbain83是否尝试存储货币值?是的,这是正确的。我不确定此行为在json字符串中是否有那么重要。但我仍然想看看现在是否有可能。警告:Floatin顾名思义,g点数字没有固定的精度。如果您想要精确的值,这对金钱特别重要,请改用。不要在金钱计算中使用浮点数。浮点数是一个值的精确近似值,而不是一个值的精确表示。如果您使用JSON进行传输,我会我强烈建议使用一个足够小的单位,你永远不需要分数,例如,美分对美元。你如何输出相同的值而不是字符串而是数值?
test={“foo”:(sprintf“%.2f”,“1.11”)。tof,“bar”:(sprintf”%.2f”,“4.55”)。tof,“abc”:(sprintf”%.2f”,“0.2”)。tof}
当你在“1.30”上使用.tof时结果格式的字符串返回到原来的版本1.3。看看我修改过的问题。我把它作为一个rspec测试来编写,以更准确地描述我所寻找的内容。随着每次编辑,这段代码变得越来越离谱。这与Ruby的目的正好相反:不要重复自己是一个驱动原则,而且这段代码重复得荒谬。humm erb可能会工作。模板会是什么样子?感觉可能会有点混乱,有一大堆条件。我会试着做一个,看看是否可以发布一个结果…谢谢!是的,我正在使用money gem。我想避免讨论“用什么类型来赚钱”的问题,因为我想把重点放在n格式问题。我想你已经回答了。。这是一个很好的答案,不过我最好建议预先设置自定义模块和/或使用改进,而不是对核心库进行修补。@mcbain83在这种情况下,我会使用
{“foo”:{“cents”:100,“currency”:“USD”}
@mudasobwa,黄色便条;)@Stefan让我们假设我无法更改预期的输出。您还建议使用money gem吗?所有格式选项似乎都是输出字符串。
class BigDecimal
  def to_json(*)
    '"%.2f"' % self
  end
end
puts my_hash.to_json
class BigDecimal
  def to_json(*)
    (self * 100).to_i.to_s
  end
end
puts my_hash.to_json