【问题标题】:Round off decimals values in all objects of a Json object将 Json 对象的所有对象中的小数值四舍五入
【发布时间】:2017-05-25 13:05:13
【问题描述】:

这是我的 JSON 字符串

[{"$id":"1","GeoName":"EAST","Value2":87.88221970554928,"Value4":90.71955219607294,"Value1":18.44377295716579,"Value3":16.732108234801206},{"$id":"2","GeoName":"WEST","Value2":87.88221970554928,"Value4":90.71955219607294,"Value1":18.44377295716579,"Value3":16.732108234801206}]"

这是我在 Stringyfying 之前的 JSON 对象

**MyObj:**


0:Object
    $id:"1"
    Value1:18.44377295716579
    GeoName:"EAST"
    Value2:87.88221970554928
    Value3:16.732108234801206
    Value4:90.71955219607294
1:Object
    $id:"2"
    Value1:18.44377295716579
    GeoName:"WEST"
    Value2:87.88221970554928
    Value3:16.732108234801206
    Value4:90.71955219607294

有没有办法在我的 JSON 的每个对象中将所有值(甚至单独的 value1、value2...)四舍五入到小数点后 2 位?

喜欢

0:Object
        $id:"1"
        Value1:18.44
        GeoName:"EAST"
        Value2:87.89
        Value3:16.73
        Value4:90.72
1:Object
        $id:"2"
        Value1:18.44
        GeoName:"WEST"
        Value2:87.89
        Value3:16.73
        Value4:90.71

我尝试过使用

Obj = JSON.parse(JSON.stringify(MyObj, function (GeoName, Value1) {
                return Value1.toFixed ? Number(Value1.toFixed(2)) : Value1;
            }));

这对我不起作用。

有没有办法通过调整上面的代码行来实现这一点,或者有更好的方法来解决这个问题?

Edit1(根据 wostex 建议的方法)

var numKeys = ['ShareValue','ReachValue','DepthValue','WidthValue'];
MyObj=Obj.map(e => Object.assign(e,Object.keys(e).filter(k => numKeys.includes(k)).map(v => Object.assign({[v]: parseFloat(e[v]).toFixed(2)}))))

这就是我的对象的样子

0:Object
       0:Object
        ReachValue:87.88
       1:Object
        DepthValue:16.73
       2:Object
        ShareValue:18.44
       3:Object
        WidthValue:90.71
        $id:"1"
        ShareValue:18.44377295716579
        GeoName:"EAST"
        ReachValue:87.88221970554928
        DepthValue:16.732108234801206
        WidthValue:90.71955219607294

编辑2

Obj = JSON.parse(JSON.stringify(BubbleObj));
var numKeys = ['ShareValue','ReachValue','DepthValue','WidthValue'];
            var MyObj=Obj.map(e => Object.assign(e,Object.keys(e).filter(k => numKeys.includes(k)).map(v => Object.assign({[v]: parseFloat(e[v]).toFixed(2)}))))

这里 Obj 有来自问题第一行的 JSON 字符串,而 BubbleObj 有我在问题中提到为 MyObj 的 Object。

【问题讨论】:

  • 仅供参考,您在对象中有多个具有相同名称的属性,这是无效的。只有最后定义的那个才可以访问
  • 似乎对我有用:jsfiddle.net/5v2dzmhe。检查控制台,你的值是四舍五入的。
  • @RoryMcCrossan 我的错,它们是两个不同名称的对象,我现在已经更改了。
  • 你可以只遍历数组和对象中的键而不解析它。
  • @Shekar.gvr 我不是指GeoName 的值,我的意思是你在每个对象中定义了两次Value3

标签: javascript jquery json asp.net-mvc


【解决方案1】:

简单的方法就是使用map - 只要你的 Value1-4 总是被称为

var input = [{"$id":"1","GeoName":"EAST","Value2":87.88221970554928,"Value4":90.71955219607294,"Value1":18.44377295716579,"Value3":16.732108234801206},{"$id":"2","GeoName":"WEST","Value2":87.88221970554928,"Value4":90.71955219607294,"Value1":18.44377295716579,"Value3":16.732108234801206}];

var output = input.map(function(e) {
    return {
      $id: e.$id,
      GeoName: e.GeoName,
      Value1: Math.round(e.Value1*100) /100,
      Value2: Math.round(e.Value2*100) /100,
      Value3: Math.round(e.Value3*100) /100,
      Value4: Math.round(e.Value4*100) /100
    }
});

console.log(output);

如果您不想对其进行硬编码,则可以查找以 Value 开头的任何密钥 - 它有点复杂。

var input = [{"$id":"1","GeoName":"EAST","Value2":87.88221970554928,"Value4":90.71955219607294,"Value1":18.44377295716579,"Value3":16.732108234801206},{"$id":"2","GeoName":"WEST","Value2":87.88221970554928,"Value4":90.71955219607294,"Value1":18.44377295716579,"Value3":16.732108234801206}];

var output = input.map(function(e) {
    return Object.keys(e).reduce(function(p,n){
       if(n.startsWith("Value"))
           p[n] = Math.round(e[n]*100)/100;
       else
           p[n] = e[n];
       return p;
    },{})
});

console.log(output);

【讨论】:

  • 它抛出一个错误,说 input.map 不是一个函数。
  • @Shekar.gvr 你已经知道你有一个字符串 - 而且你一定知道你需要JSON.parse你的字符串。
  • 以 IE 不支持的结尾和开头。您可以建议任何解决方法吗?
  • @Shekar.gvr mdn 通常包含用于不受支持的浏览器的 polyfil:developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
  • 我如何使用该链接中解释的 polly 填充方法来满足我的要求
【解决方案2】:

顺便说一句,您的第一个字符串中有重复的键“Value3”,除此之外,您可以执行以下操作:

var j = [{"$id":"1","GeoName":"EAST","ShareValue":87.88221970554928,"ReachValue":90.71955219607294,"DepthValue":18.44377295716579,"WidthValue":16.732108234801206},{"$id":"2","GeoName":"WEST","ShareValue":87.88221970554928,"ReachValue":90.71955219607294,"DepthValue":18.44377295716579,"WidthValue":16.732108234801206}];

// your numeric keys
var numKeys = ['ShareValue','ReachValue','DepthValue','WidthValue'];

var res = j.map(e => Object.assign(e, // rewrite each object
  ...Object.keys(e).filter(k => numKeys.indexOf(k) > -1) // pick keys which include 'Value'
    .map(v => Object.assign({[v]: parseFloat(e[v]).toFixed(2)})) // chop numbers
  ))
  
console.log(res)

【讨论】:

  • 还有endsWith() 方法吗?实际上我有像 ShareValue,ReachValue,DepthValue,WidthValue 这样的值,我在发布问题时将其转换为 Value1,Value2...。
  • @Shekar.gvr 已为您的密钥更新。还有endsWith,但我在这里使用includes 使其更通用。
  • 我试过用你的方法,但是对象结构被篡改了。 4 个值中的每一个都作为 4 个新对象添加到主对象中。请参考上述帖子中的edit1。
  • 什么是MyObj?我的代码适用于名为JSON string 的问题的第一行,即对象数组。然后展示你的真实对象。
  • 感谢您的帮助,请参阅编辑 2,其中我为您提供了我的应用程序中的实际代码。
猜你喜欢
  • 1970-01-01
  • 2012-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-02
  • 1970-01-01
  • 2021-05-14
  • 2023-03-24
相关资源
最近更新 更多