1

Having input like the below:

[
  {
    gameId: id_0,
    groups: [1]
  },
  {
    gameId: id_1,
    groups: [2]
  },
  {
    gameId: id_2,
    groups: [1, 2]
  },
  {
    gameId: id_3,
    groups: [3]
  }
]

I would like my reduce to result in an array of objects like:

[
  {
    group: 1,
    data: [
      id_0, id_2 // gameId
    ]
  },
  {
    group: 2,
    data: [
      id_1, id_2
    ]
  },
  {
    group: 3,
    data: [
      id_3
    ]
  }
]

I was able to partially solve this by utilising array indexes. The code I have currently is:

groupByArr = parameter => data => data.reduce((acc, curr) => {
  curr[parameter].forEach(key => {
    if (acc[key]) {
      acc[key].push(curr)
    } else {
      acc[key] = [curr]
    }
  })
  return acc
}, [])

which produces an array of arrays where main array index is the group id:

[
  empty,
  1: [
    id_0, id_2
  ],
  2: [
    id_1, id_2
  ],
  3: [
    id_3
  ]
]

6 Answers 6

1

You can use Array.prototype.reduce() combined with Array.prototype.forEach() and Array.prototype.push() to return an Object and finally get the values with Object.values()

Code:

const data = [{gameId: 'id_0',groups: [1]},{gameId: 'id_1',groups: [2]},{gameId: 'id_2',groups: [1, 2]},{gameId: 'id_3',groups: [3]}]
const result = Object.values(data.reduce((acc, {gameId, groups}) => {
  groups.forEach(group => {
    acc[group] = acc[group] || { group, data: [] }
    acc[group].data.push(gameId)
  })
  return acc
}, {}))

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

2 Comments

Appreciate your work, thanks for keeping your answer up to date!
@user0101 glad to help!
0

Let arr be the variable containing data in following format:

[
  empty,
  1: [
    id_0, id_2
  ],
  2: [
    id_1, id_2
  ],
  3: [
    id_3
  ]
]

Then following code might do:-

for(let i=1;i<arr.length;i++){
    arr[i-1] = {group:i,data:arr[i]};
}
arr[arr.length-1] = undefined; // To Prevent Unnecessary Errors
delete arr[arr.length-1]; // To Prevent Unnecessary Errors
arr.length -= -1;

Now arr will be in following format:-

[
  {
    group: 1,
    data: [
      id_0, id_2
    ]
  },
  {
    group: 2,
    data: [
      id_1, id_2
    ]
  },
  {
    group: 3,
    data: [
      id_3
    ]
  }
]

Hope it helps. Tell me if I Misunderstood your question.

Comments

0

Use an object as acc, then add objects to it:

  if (acc[key]) {
    acc[key].data.push(curr)
  } else {
     acc[key] = { group: key, data: [curr] };
  }

And finally, turn the returned object into an array:

 const result = Object.values(hash);

Comments

0

Try this

const data = [
    {gameId: 'id_0',groups: [1]},
    {gameId: 'id_1',groups: [2]},
    {gameId: 'id_2',groups: [1, 2]},
    {gameId: 'id_3',groups: [3]}
]

const single_id = data.filter(i => i.groups.length === 1)
const multiple_ids = data.filter(i => i.groups.length > 1)
let res = [];
single_id.map(i => {
    let data = {group: i.groups[0], data: [i.gameId]}
    multiple_ids.forEach(o => o.groups.includes(i.groups[0]) && (data.data.push(o.gameId)))
    res.push(data)
})
console.log(res)

Comments

0
`let b = [
  {
    gameId: "id_0",
    groups: [1]
  },
  {
    gameId: "id_1",
    groups: [2]
  },
  {
    gameId: "id_2",
    groups: [1, 2]
  },
  {
    gameId: "id_3",
    groups: [3]
  }
];

let d = new Map(); ;
b.forEach(function(a){
    a.groups.forEach(function(a1){
        if(d.get(a1)){
            d.get(a1).push(a.gameId);
        }else{
            d.set(a1, [a.gameId]);
        }
    });
});`

Comments

0

You should try this one. Using reduce in grouped scenarios is the best thing JavaScript provides us

let arr = [
{
        gameId: "id_0",
        groups: [1]
    },
    {
        gameId: "id_1",
        groups: [2]
    },
    {
        gameId: "id_2",
        groups: [1, 2]
    },
    {
        gameId: "id_3",
        groups: [3]
    }
];


const grouped = arr.reduce((acc, current) => {
    for(let x of current.groups){
        if(!acc[x]) {
            acc[x] = {group: x, data:[current.gameId]}
        } else {
            acc[x].data.push(current.gameId)
        }
    }
    return acc
},{});

console.log(Object.values(grouped))

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.