使用 JavaScript 映射和减少 JSON 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34010342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:48:17  来源:igfitidea点击:

Map and Reduce JSON Objects with JavaScript

javascriptjson

提问by Mr. Concolato

Consider this JSON object below:

考虑下面的这个 JSON 对象:

{
   "cells":[
      {
         "count":"1",
         "gdp_growth__avg":1.90575802503285,
         "geo__name":"united states of america",
         "time":1990
      },
      {
         "count":"1",
         "gdp_growth__avg":9.17893670154459,
         "geo__name":"china",
         "time":1991
      },
      {
         "count":"1",
         "gdp_growth__avg":-5.04693945214571,
         "geo__name":"russia",
         "time":1991
      },
      {
         "count":"1",
         "gdp_growth__avg":-0.0622142217811472,
         "geo__name":"botswana",
         "time":1991
      },
      {
         "count":"1",
         "gdp_growth__avg":14.2407063986337,
         "geo__name":"china",
         "time":1992
      },
      {
         "count":"1",
         "gdp_growth__avg":-14.5310737731921,
         "geo__name":"russia",
         "time":1992
      },
      {
         "count":"1",
         "gdp_growth__avg":3.55494453739944,
         "geo__name":"united states of america",
         "time":1992
      },
      {
         "count":"1",
         "gdp_growth__avg":13.9643147001603,
         "geo__name":"china",
         "time":1993
      },
      {
         "count":"1",
         "gdp_growth__avg":-8.66854034194856,
         "geo__name":"botswana",
         "time":1993
      },
      {
         "count":"1",
         "gdp_growth__avg":2.74204850437989,
         "geo__name":"united states of america",
         "time":1993
      },
      {
         "count":"1",
         "gdp_growth__avg":4.04272516401846,
         "geo__name":"united states of america",
         "time":1994
      },
      {
         "count":"1",
         "gdp_growth__avg":13.0806818010789,
         "geo__name":"china",
         "time":1994
      },
      {
         "count":"1",
         "gdp_growth__avg":-12.5697559787493,
         "geo__name":"russia",
         "time":1994
      },
      {
         "count":"1",
         "gdp_growth__avg":10.9249803004994,
         "geo__name":"china",
         "time":1995
      },
      {
         "count":"1",
         "gdp_growth__avg":-4.14352840666389,
         "geo__name":"russia",
         "time":1995
      },
      {
         "count":"1",
         "gdp_growth__avg":2.71655384149574,
         "geo__name":"united states of america",
         "time":1995
      },
      {
         "count":"1",
         "gdp_growth__avg":10.0085233990531,
         "geo__name":"china",
         "time":1996
      },
      {
         "count":"1",
         "gdp_growth__avg":3.79848988541973,
         "geo__name":"united states of america",
         "time":1996
      }
]
}

I would to Map and Reduce and generate a new object containing a summation of the GDP growth for all the countries in the above JSON that might look roughly like this:

我会映射和减少并生成一个新对象,其中包含上述 JSON 中所有国家/地区的 GDP 增长总和,大致如下所示:

{  
  {
     "gdp_growth__avg":46.23,
     "geo__name":"united states of america",
  },
  {
     "gdp_growth__avg":16.23,
     "geo__name":"china",
  },
  {
     "gdp_growth__avg":36.23,
     "geo__name":"russia",
  },
  {
     "gdp_growth__avg":26.23, 
     "geo__name":"botswana",
     "time":1991
  }
 }

I have looked at mapand reduceand am not sure how best to proceed.

我查看了mapreduce,但不确定如何最好地进行。

I was thinking something like this might be moving in the right directions, but does not seem to do what I was expecting:

我在想这样的事情可能会朝着正确的方向发展,但似乎并没有达到我的预期:

      var arr = [{x:1},{x:2},{x:4}];

      arr.reduce(function (a, b) {
        return {x: a.x + b.x};
      });

      console.log(arr); //Outputs that same initial array

While I recognize that it is probably better and easier to do this on the server-side, I am wondering if what I am trying to do can be done on the client side with JavaScript. Any suggestions? Thanks in advance.

虽然我认识到在服务器端执行此操作可能更好更容易,但我想知道是否可以使用 JavaScript 在客户端完成我想要做的事情。有什么建议?提前致谢。

采纳答案by marsgpl

Try this:

尝试这个:

var data = { cells:[...] };

var r = data.cells.reduce(function(pv, cv) {
    if ( pv[cv.geo__name] ) {
        pv[cv.geo__name] += cv.gdp_growth__avg;
    } else {
        pv[cv.geo__name] = cv.gdp_growth__avg;
    }
    return pv;
}, {});

console.log(r);

Output example:

输出示例:

    { 
      'united states of america': 18.76051995774611,
      'china': 71.39814330096999,
      'russia': -36.291297610751,
      'botswana': -8.730754563729707 
   }

回答by Mike Baranczak

The Array.reducemethod doesn't change the array object, it returns the results in a new array.

Array.reduce方法不会更改数组对象,而是在新数组中返回结果。

回答by Hunan Rostomyan

You can try something like this:

你可以尝试这样的事情:

var data = {"cells": [...]};

data.cells.map(function(datum) {
  return {
    geo__name: datum.geo__name,
    gdp_growth__avg: data.cells.filter(function(o) {
      return o.geo__name === datum.geo__name;
    }).reduce(function(sum, o) {
      return sum + o.gdp_growth__avg;
    }, 0)
  };
})

Needless to say, you can extract other properties from datumas well, such as time. I haven't.

不用说,您也可以从中提取其他属性datum,例如time. 我没有。

回答by Abhilash

I tried to do with better time complexity:

我试图用更好的时间复杂度来做:

let ans = [];
let map = new Map();
ques.cells.forEach(x => {
if(map[x.geo__name]){
map.set(x.geo__name, map[x.geo__name] + x.gdp_growth__avg);
}else{
map.set(x.geo__name,x.gdp_growth__avg);
}
});

map.forEach((v,k)=>{
ans.push({"geo__name":k, "gdp_growth__avg":v});
});
ques.cells = ans;

with solution looking like this:

解决方案如下所示:

[
  {
    "geo__name": "united states of america",
    "gdp_growth__avg": 3.79848988541973
  },
  {
    "geo__name": "china",
    "gdp_growth__avg": 10.0085233990531
  },
  {
    "geo__name": "russia",
    "gdp_growth__avg": -4.14352840666389
  },
  {
    "geo__name": "botswana",
    "gdp_growth__avg": -8.66854034194856
  }
]