1

my array that i download from the server looks like this,

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' } ]

If i need to create a nested object( # of exps, belonging to respective teams, organized by user) from the above array how would i go about it. my resulting nested object shud look like this, (notice alpha has 3 exps belonging to team c) and so on and so forth

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

you can do this traditionally with couple of for loops. but is there a easier way to reduce the for loop cycles and get this created. the caveat is, this must be strict JS I do not know how many users/teams/exps there might be. there may be 50 different users/1000 different experiments . So i can't hardcode any exp names/users/ etc.

2
  • 2
    don't stuff the ids in as values. use them as keys. data['alpha'] is far easier to deal with than having to scan your parent array every time to figure out which index id:alpha is in. Commented Mar 23, 2016 at 15:24
  • @MarcB the reason i event want to create this nested object is becasue this is the format the third party chart library i use, expects Commented Mar 23, 2016 at 15:27

2 Answers 2

1

This proposal uses a single loop with a temporary object for the references to the result array's arrays.

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>');

Sign up to request clarification or add additional context in comments.

Comments

0

Here is a solution with Array.prototype.reduce, which I feel is a bit easier to read and reason about.

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.