创建一个原始的json到嵌套的json对象 - javascript

时间:2016-03-23 15:18:26

标签: javascript json parsing nested

我从服务器下载的数组看起来像这样,

array=[ { icon: 'm-warning',
    color: '#FDC204',
    name: 'exp1',
    team: 'c',
    user: 'alpha' },
  { icon: 'm-puzzle',
    color: '#86AF45',
    name: 'exp2',
    team: 'c',
    user: 'alpha' },
  { icon: 'm-refresh',
    color: '#77A746',
    name: 'exp3',
    team: 'c',
    user: 'alpha' },
  { icon: 'm-puzzle',
    color: '#86AF45',
    name: 'exp3',
    team: 'a',
    user: 'beta' },
  { icon: 'm-clock',
    color: '#4677A7',
    name: 'exp4',
    team: 'b',
    user: 'beta' },
  { icon: 'm-warning',
    color: '#FDC204',
    name: 'exp5',
    team: 'a',
    user: 'gamma' } ]

如果我需要从上面的数组创建一个嵌套对象(属于各个团队的exps,属于各个团队),我将如何处理它。我得到的嵌套对象shud看起来像这样,(注意alpha有3个属于团队c的exp),依此类推等等

[{
  id: 'gamma',
  data: [
    ['a', 1]
  ]
},
{
  id: 'beta',
  data: [
    ['a', 1],
    ['b', 1]
  ]
},
{
  id: 'alpha',
  data: [
    ['c', 3]
  ]
}]

你可以通过几个for循环传统地执行此操作。但有没有更简单的方法来减少for循环周期并创建它。需要注意的是,这必须是严格的JS我不知道有多少用户/团队/ exps。可能有50个不同的用户/ 1000个不同的实验。所以我无法对任何exp名称/用户/等进行硬编码。

2 个答案:

答案 0 :(得分:1)

此提议使用带有临时对象的单个循环来引用结果数组的数组。



var array = [{ icon: 'm-warning', color: '#FDC204', name: 'exp1', team: 'c', user: 'alpha' }, { icon: 'm-puzzle', color: '#86AF45', name: 'exp2', team: 'c', user: 'alpha' }, { icon: 'm-refresh', color: '#77A746', name: 'exp3', team: 'c', user: 'alpha' }, { icon: 'm-puzzle', color: '#86AF45', name: 'exp3', team: 'a', user: 'beta' }, { icon: 'm-clock', color: '#4677A7', name: 'exp4', team: 'b', user: 'beta' }, { icon: 'm-warning', color: '#FDC204', name: 'exp5', team: 'a', user: 'gamma' }],
    grouped = function (array) {
        var o = {}, r = [];
        array.forEach(function (a) {
            if (!(a.user in o)) {
                o[a.user] = { _: { id: a.user, data: [] } };
                r.push(o[a.user]._);
            }
            if (!(a.team in o[a.user])) {
                o[a.user][a.team] = [a.team, 0];
                o[a.user]._.data.push(o[a.user][a.team]);
            }
            o[a.user][a.team][1]++;
        });
        return r;
    }(array);

document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这是一个Array.prototype.reduce的解决方案,我觉得这个解决方案更容易理解和推理。

let result = array.reduce((accumulated, value) => {
  // find existing user
  let user = accumulated.find(item => item.id === value.user)
  if (user) {
    // find existing team
    let team = user.data.find(item => item[0] === value.team)
    if (team) {
      // existing team found, increase count
      team[1]++
    } else {
      // existing team not found, add team
      user.data.push([ value.team, 1 ])
    }
  } else {
    // existing user not found, add user
    accumulated.push({
      id: value.user,
      data: [
        [ value.team, 1 ]
      ]
    })
  }
  return accumulated
}, [])  // start with empty array

Here is a jsbin to try it out in your browser