在应用程序脚本中从 API 合并数组 JSON return

merge array JSON return from API in app script

我使用应用程序脚本从 API 数组中获取 JSON 数组:

var a = '[{numbers=228, id=4152, gendar=female}, {numbers=978, id=8479, gendar=male}, {numbers=101, id=8479, gendar=male}, {numbers=356, id=4152, gendar=female}]';

我想合并每个具有相同 ID 的数组。 return 需要这样的:

[{numbers=584, id=4152, gendar=female}, {numbers=779, id=8479, gendar=male}]

大概是这样的:

var jsn = [
    { numbers: '228', id: '4152', gendar: 'female' },
    { numbers: '356', id: '4152', gendar: 'female' },
    { numbers: '978', id: '8479', gendar: 'male' },
    { numbers: '101', id: '8479', gendar: 'male' },
];

var obj = {};
for (let o of jsn)
  try { obj[o.id].numbers = +obj[o.id].numbers + +o.numbers }
  catch(e) { obj[o.id] = o }

var arr = Object.values(obj);
console.log(arr);

输出:

[
  { numbers: 584,  id: '4152', gendar: 'female' },
  { numbers: 1079, id: '8479', gendar: 'male' }
]

更新

这里是更改 'female' --> 'woman' 并计算每个 ID 的平均数的代码变体:

var jsn = [
  { numbers: '228', id: '4152', gendar: 'female' },
  { numbers: '356', id: '4152', gendar: 'female' },
  { numbers: '978', id: '8479', gendar: 'male' },
  { numbers: '101', id: '8479', gendar: 'male' },
];

// change 'female' --> 'woman'
// jsn = JSON.parse(JSON.stringify(jsn).replace(/female/g, 'woman'));

// make the object {id: {id, numbers: [array], gendar}, id:{}, ... }
var obj = {};
for (let o of jsn) {
  try {
    try { obj[o.id].numbers.push(o.numbers) }
    catch (e) { obj[o.id].numbers = [o.numbers] }
  }
  catch (e) {
    o.numbers = [o.numbers];
    obj[o.id] = o;
  }
}

// 
const average = arr => arr.reduce((p, c) => +p + +c, 0) / arr.length;

// replace the arrays with its average number within the object
for (let id in obj) obj[id].numbers = average(obj[id].numbers);

// replace 'female' --> 'woman' in every 'id' of the 'obj'
for (let id in obj) if (obj[id].gendar == 'female') obj[id].gendar = 'woman';

var arr = Object.values(obj);
console.log(arr);

预期输出:

[
  { numbers: 292, id: '4152', gendar: 'woman' },
  { numbers: 539.5, id: '8479', gendar: 'male' }
]

更新 2

或者,您可以通过以下简单循环将 'female' 更改为 'woman':

for (let id in obj) if (obj[id].gendar == 'female') obj[id].gendar = 'woman';

查看更新后的代码。

您可以使用 Array.prototype.reduce()id 分组,然后
使用 Object.values 结果如下:

const arr = [
  {numbers: 228, id: 4152, gendar: 'female'},
  {numbers: 978, id: 8479, gendar: 'male'},
  {numbers: 101, id: 8479, gendar: 'male'}, 
  {numbers: 356, id: 4152, gendar: 'female'}
];


const res = arr.reduce((acc, curr) => {
  if(acc[curr.id]) {
    acc[curr.id].numbers += curr.numbers;
  } else {
    acc[curr.id] = curr
  }

  return acc;
}, {});

console.log(Object.values(res));

合并对象

function merge() {
  const arr = JSON.parse(Your JSON goes here);
  const x = arr.reduce((a, c, i) => {
    let p = `${c.id}/${c.gendar}`;//name of each object is a string made  up off the id and the gendar
    if (!a.obj.hasOwnProperty(p)) {
      a.obj[p] = c;
      a.obj.pA.push(p);//collects a list of all new object names so that I can iterate through them after adding all of the numbers together for identical property names
    } else {
      a.obj[p].numbers += Number(c.numbers);//If there are properties with identical names id/gendar then I add the numbers together the final array is placed in a.oA by the function getArray() which is inside of a.
    }
    return a;
  }, { obj: { pA: [] }, oA: [], getArray: function () { this.obj.pA.forEach(p => { this.oA.push(this.obj[p]) });return this.oA; } }).getArray();
  Logger.log(JSON.stringify(x));
}

生成数据

function lfunkdata() {
  let arr = [...Array.from(new Array(Math.floor((Math.random() * 20) + 5)).keys(), x => {
    let a = Math.floor((Math.random() * 9000) + 10);//c.numbers
    let b = Math.floor((Math.random() * 10) + 1);//c.id
    let c = Math.round(Math.random() * 1) ? "Male" : "Female";//c.gendar
    return { numbers: a, id: b, gendar: c };
  })];
  let r = JSON.stringify(arr)
  Logger.log(r);
  return r;
}

模拟数据:

[{"numbers":5115,"id":9,"gendar":"Female"},{"numbers":6598,"id":8,"gendar":"Female"},{"numbers":162,"id":10,"gendar":"Female"},{"numbers":691,"id":8,"gendar":"Male"},{"numbers":684,"id":8,"gendar":"Female"},{"numbers":6941,"id":6,"gendar":"Male"},{"numbers":5822,"id":10,"gendar":"Male"},{"numbers":7453,"id":9,"gendar":"Female"},{"numbers":2663,"id":7,"gendar":"Male"},{"numbers":4031,"id":7,"gendar":"Female"},{"numbers":8581,"id":7,"gendar":"Male"},{"numbers":8940,"id":3,"gendar":"Male"},{"numbers":3622,"id":4,"gendar":"Male"},{"numbers":1842,"id":8,"gendar":"Female"},{"numbers":1653,"id":9,"gendar":"Male"},{"numbers":2085,"id":3,"gendar":"Female"},{"numbers":918,"id":5,"gendar":"Female"},{"numbers":2470,"id":7,"gendar":"Female"},{"numbers":8169,"id":4,"gendar":"Male"},{"numbers":754,"id":6,"gendar":"Female"},{"numbers":7444,"id":1,"gendar":"Male"},{"numbers":6094,"id":1,"gendar":"Male"}]

结果:

[{"numbers":12568,"id":9,"gendar":"Female"},{"numbers":9124,"id":8,"gendar":"Female"},{"numbers":162,"id":10,"gendar":"Female"},{"numbers":691,"id":8,"gendar":"Male"},{"numbers":6941,"id":6,"gendar":"Male"},{"numbers":5822,"id":10,"gendar":"Male"},{"numbers":11244,"id":7,"gendar":"Male"},{"numbers":6501,"id":7,"gendar":"Female"},{"numbers":8940,"id":3,"gendar":"Male"},{"numbers":11791,"id":4,"gendar":"Male"},{"numbers":1653,"id":9,"gendar":"Male"},{"numbers":2085,"id":3,"gendar":"Female"},{"numbers":918,"id":5,"gendar":"Female"},{"numbers":754,"id":6,"gendar":"Female"},{"numbers":13538,"id":1,"gendar":"Male"}]