Search code examples
listvb.netlinq

Filtering and grouping in list based on condition


I have a list object with properties

[
   {
      "Id": 123,
      "Name": "Admin",
      "Group": 1,
      "OldValue": 2,
      "LastestValue": 1
   },
   {
      "Id":123,
      "Name": "Admin",
      "Group": 1,
      "OldValue": 0,
      "LastestValue": 1
   },
   {
      "Id": 456,
      "Name": "Worker",
      "Group": 2,
      "OldValue": 0,
      "LastestValue": 1
   }
]

I'm able to extract data based on Name.

Dim result = myList.GroupBy(Function(i) i.Name).Where(Function(p) p.Count >1).SelectMany(Function(k) k).ToList()

But doing as above way I missed out the Id: 456 values. I want to filter out the entries and do a condition check, for the name like "Admin", I want to compare its first record.LastestValue vs last record.LastestValue if they match, save the last record item entry and disregard anything else and also preserve the records that don't have name with count > 1.

Expected result:

[
   {
      "Id": 123,
      "Name": "Admin",
      "Group": 1,
      "OldValue": 0,
      "LastestValue": 1
   },
   {
      "Id": 456,
      "Name": "Worker",
      "Group": 2,
      "OldValue": 0,
      "LastestValue": 1
   }
]

Solution

  • You are tagging the C# and assume that you are accepting the C# answer.

    Within each group, you can add logic to check that the LastestValue of both first and last records are the same. This works fine too for the group with single record as the first and last record will refer to the same record.

    If the condition unmet, returns null and ensure that you need to remove the records which are null for the result.

    var result = myList.GroupBy(x => x.Name)
                .Select(g => new
                        {
                            Name = g.Key,
                            Data = g.First().LastestValue == g.Last().LastestValue
                                ? g.Last()
                                : null
                        })
                .Select(x => x.Data)
                .Where(x => x != null)
                .ToList();
    

    For VB.NET it should be:

    Dim result = myList.GroupBy(Function(x) x.Name).Select(
                Function(g) New With {
                    Key.Name = g.Key, 
                    Key.Data = If(g.First().LastestValue = g.Last().LastestValue, g.Last(), Nothing)
                }).Select(Function(x) x.Data).Where(Function(x) x IsNot Nothing).ToList()