7

I have the list of objects of the following class,

class Invoice
{
   public int InvoiceNumber;
   public string CustomerName;
   public bool IsDupe;
}

The invoice numbers can be duplicate or there can even be a case of 4 invoices , all with the same number.

I need to set the IsDupe flag on all except one of the invoice object. One approach is the brute force method of having a list of invoice numbers and comparing each one to flag. I have also tried this question . Is there any better syntactical way to do it ? TIA

Community
  • 1
  • 1
SJMan
  • 1,547
  • 2
  • 14
  • 37

2 Answers2

5

This works.

var invs = new List<Invoice> { new Invoice { InvoiceNumber = 1 }, 
                               new Invoice { InvoiceNumber = 1 }, 
                               new Invoice { InvoiceNumber = 1 },
                               new Invoice { InvoiceNumber = 2 }, 
                               new Invoice { InvoiceNumber = 3 }, 
                               new Invoice { InvoiceNumber = 3 } 
                             };

invs.ForEach(i => i.IsDupe = true);
invs.GroupBy (i => i.InvoiceNumber)
    .Select(g => g.First())
    .ToList()
    .ForEach(i => i.IsDupe = false);

Produces

1 null False 
1 null True 
1 null True 
2 null False 
3 null False 
3 null True 

Alternatively, you could call the property IsNotDupe and take advantage of the fact that the boolean defaults to false (you can remove the first ForEach)

Rob
  • 26,989
  • 16
  • 82
  • 98
4

Assuming that you have a list of these elements, you can use LINQ and utilize ForEach extension:

List<Invoice> invoices = /* */;

invoices
    .GroupBy(inv => inv.InvoiceNumber)
    .ForEach(group => group.Skip(1).ForEach(notFirst => notFirst.IsDupe = true));

It groups invoices up by InvoiceNumber, and if a group contains more than one item, then it sets IsDupe to true for all except for the first one.

However, using ForEach seems to be non-LINQ-friendly and less readable for me.
It looks great with foreach:

foreach (var group in invoices.GroupBy(inv => inv.InvoiceNumber))
{
    foreach (var notFirstItem in group.Skip(1))
    {
        notFirstItem.IsDupe = true;
    }
}

Now, it is absolutely readable - take every group, take all items except for the first one, and mark as IsDupe = true.

Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101