Search code examples
javascriptecmascript-6filterreducees6-map

Format array of objects with varied data structures


I have the following data:

   const match = 'A'

   const data = [
    {
        age: "12", 
        group: [
            {club: 'A'},
            {club: 'B'}
        ],
        active: {
            sjbuas777: {club: 'A'},
            122kk7dgs: {club: 'B'}
        }
    },
    {
        age: "11", 
        group: [
            {club: 'A'},
            {club: 'D'}
        ],
        active: {
            djs7skww3: {club: 'C'},
            sjhsjs72k: {club: 'B'}
        }
    },
        {
        age: "12", 
        group: [
            {club: 'A'},
            {club: 'D'}
        ],
        active: {
            shshs6kka: {club: 'A'},
            5d8jallo1: {club: 'C'}
        }
    },
    {
        age: "13", 
        group: [
            {club: 'C'},
            {club: 'S'}
        ],
        active: {
            kks7sjkla: {club: 'A'},
            jjs66s5as: {club: 'B'}
        }
    }
]

How can I group the data by age and give a count of groups and active where the club value is equal to match for that age? Note the keys in the active object are unknown.

The desired output is:

[
    {age: "11", group: 1, active: 0},
    {age: "12", group: 2, active: 2},
    {age: "13", group: 0, active: 1}
]

Many thanks in advance.

EDIT

I wanted to show where I am at so far:

 function getCountsByAge() {
    return [
      ...new Set([
        ...Object.values(data)
            .filter(d => d.group
            .some(({club}) => club === match))
            .map(result => result)

      ])
    ]
  }

Solution

  • You could create a Map keyed by age, with all counts set to zero, and then increment those counts by filtering for where the club matches:

    const match = "A";
    const data = [{age: "12",group: [{club: 'A'},{club: 'B'}],active: {sjbuas777: {club: 'A'},"122kk7dgs": {club: 'B'}}}, {age: "11",group: [{club: 'A'},{club: 'D'}],active: {djs7skww3: {club: 'C'},sjhsjs72k: {club: 'B'}}}, {age: "12",group: [{club: 'A'},{club: 'D'}],active: {shshs6kka: {club: 'A'},"5d8jallo1": {club: 'C'}}}, {age: "13",group: [{club: 'C'},{club: 'S'}],active: {kks7sjkla: {club: 'A'},jjs66s5as: {club: 'B'}}}];
    
    const map = new Map(data.map(({age}) => [age, { age, group: 0, active: 0 }]));
    for (const {age, group, active} of data) {
        map.get(age).group += group.filter(({club}) => club === match).length;
        map.get(age).active += Object.values(active).filter(({club}) => club === match).length;
    }
    const result = [...map.values()];
    
    console.log(result);