Home > Enterprise >  Javascript - Grouping and filtering a list of lists
Javascript - Grouping and filtering a list of lists

Time:03-21

I have a value events which is a list of lists with maps that look like this:

[
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 831,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 832,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T16:25:00Z",
            "type": "deviated-manually-overridden",
            "id": 842,
            "createdAt": "2022-03-20T16:26:00.363630Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T16:38:00Z",
            "type": "deviated-manually-overridden",
            "id": 844,
            "createdAt": "2022-03-20T16:38:46.352751Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T20:31:00Z",
            "type": "collected-manually-overridden",
            "id": 846,
            "createdAt": "2022-03-20T20:32:18.046346Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 829,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-20T16:25:00Z",
            "type": "deviated-manually-overridden",
            "id": 843,
            "createdAt": "2022-03-20T16:26:00.363630Z",
            "createdBy": "47"
        },
        {
            "packageId": "2738",
            "eventTime": "2022-03-20T16:38:00Z",
            "type": "deviated-manually-overridden",
            "id": 845,
            "createdAt": "2022-03-20T16:38:46.352751Z",
            "createdBy": "47"
        },
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 830,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 833,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 834,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ]
]

I would like to group this list inside of a list by map's packageId, so that every map with the same packageId is part of one list. At the same time I would also like to filter out the maps that have the same packageId, type and eventTime, so that I have only one of each with the same values of those fields. What I want to achieve is this:

[
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 831,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T16:25:00Z",
            "type": "deviated-manually-overridden",
            "id": 842,
            "createdAt": "2022-03-20T16:26:00.363630Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T16:38:00Z",
            "type": "deviated-manually-overridden",
            "id": 844,
            "createdAt": "2022-03-20T16:38:46.352751Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T20:31:00Z",
            "type": "collected-manually-overridden",
            "id": 846,
            "createdAt": "2022-03-20T20:32:18.046346Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 832,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        },
        {
            "packageId": "2738",
            "eventTime": "2022-03-20T16:25:00Z",
            "type": "deviated-manually-overridden",
            "id": 843,
            "createdAt": "2022-03-20T16:26:00.363630Z",
            "createdBy": "47"
        },
        {
            "packageId": "2738",
            "eventTime": "2022-03-20T16:38:00Z",
            "type": "deviated-manually-overridden",
            "id": 845,
            "createdAt": "2022-03-20T16:38:46.352751Z",
            "createdBy": "47"
        }
    ]
]

I am not sure how can I achieve that kind of data structure with groupBy or filter. I have tried with:

events.groupBy(listOfEvents => listOfEvents.map(e => e.get('packageId')))

But, that is obviously not working. How can I do this?

Update:

I have tried with creating a Map based on answer suggestions:

const grouped = Map<string, List<Event>>()
  events.map(list => list.map(event => {
    const packageId = event?.get('packageId')
    console.log('packageId ', packageId)
    if (packageId) {
      console.log('grouped packageId: ', grouped.get(packageId))
      if (!grouped.get(packageId)) {
        grouped.set(packageId, List<Event>())
      }
      const updatedList = grouped.get(packageId)?.push(event)
      console.log('updatedList: ', updatedList)
      if (updatedList) grouped.set(packageId, updatedList)
      console.log('grouped: ', grouped)
    }
  }))

  console.log('grouped ', grouped)

But, this is not setting any value into Map, I see that packageId is logged, but everything else is undefined and grouped is of size 0. What am I doing wrong here?

CodePudding user response:

Try this

var grouped {};
var lists = [
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 831,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 832,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T16:25:00Z",
            "type": "deviated-manually-overridden",
            "id": 842,
            "createdAt": "2022-03-20T16:26:00.363630Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T16:38:00Z",
            "type": "deviated-manually-overridden",
            "id": 844,
            "createdAt": "2022-03-20T16:38:46.352751Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T20:31:00Z",
            "type": "collected-manually-overridden",
            "id": 846,
            "createdAt": "2022-03-20T20:32:18.046346Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 829,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-20T16:25:00Z",
            "type": "deviated-manually-overridden",
            "id": 843,
            "createdAt": "2022-03-20T16:26:00.363630Z",
            "createdBy": "47"
        },
        {
            "packageId": "2738",
            "eventTime": "2022-03-20T16:38:00Z",
            "type": "deviated-manually-overridden",
            "id": 845,
            "createdAt": "2022-03-20T16:38:46.352751Z",
            "createdBy": "47"
        },
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 830,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 833,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 834,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ]
]

lists.map(list=>list.map(byPack=>{
   if (!grouped[byPack.packageId]){
       grouped[byPack.packageId]=[];
    }

    grouped[byPack.packageId].push(byPack);
});

console.log(grouped);

CodePudding user response:

One method would be transfer everything into an object using packageId as key, during that process generate an id for each object based on it's packageId, type and eventTime, ignore it if that id already has been transferred and than extract it's values into array:

const data = [
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 831,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 832,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T16:25:00Z",
            "type": "deviated-manually-overridden",
            "id": 842,
            "createdAt": "2022-03-20T16:26:00.363630Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T16:38:00Z",
            "type": "deviated-manually-overridden",
            "id": 844,
            "createdAt": "2022-03-20T16:38:46.352751Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-20T20:31:00Z",
            "type": "collected-manually-overridden",
            "id": 846,
            "createdAt": "2022-03-20T20:32:18.046346Z",
            "createdBy": "47"
        },
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 829,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-20T16:25:00Z",
            "type": "deviated-manually-overridden",
            "id": 843,
            "createdAt": "2022-03-20T16:26:00.363630Z",
            "createdBy": "47"
        },
        {
            "packageId": "2738",
            "eventTime": "2022-03-20T16:38:00Z",
            "type": "deviated-manually-overridden",
            "id": 845,
            "createdAt": "2022-03-20T16:38:46.352751Z",
            "createdBy": "47"
        },
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 830,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2721",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 833,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ],
    [
        {
            "packageId": "2738",
            "eventTime": "2022-03-15T11:24:12.200864Z",
            "type": "created",
            "id": 834,
            "createdAt": "2022-03-15T11:24:12.200864Z",
            "createdBy": "47"
        }
    ]
];
let groups = {};
for(let i = 0, filter = {}; i < data.length; i  )
{
  for(let j = 0; j < data[i].length; j  )
  {
    const d = data[i][j],
          id = d.packageId "_" d.type "_" d.eventTime;

    if (id in filter)
      continue;

    filter[id] = "";
    if (!groups[d.packageId])
      groups[d.packageId] = [];

    groups[d.packageId].push(d);
  }
}

groups = Object.values(groups);
console.log(groups);

P.S. This can be visually simplified by using Array.map() instead of for loops, but it will be slightly slower.

  • Related