dstewart101
dstewart101

Reputation: 1112

linq query and use result to set property

I have a list of objects and i need to set a field based on whether or not a field holds a unique value.

Consider a ticket class with two properties

public class Ticket
{
    public string TicketNumber { get; set; }

    public bool IsUnique { get; set; }
}

I receive a list of tickets and pass these to a function:

 IList<Ticket>

Using linq I would like to iterate over this list and if a given ticket number is unique in that list, set the bool IsUnique to true.

I have the following so far

public void UpdateTickets(IList<Ticket> Tickets)
    {
        foreach (var ticket in tickets)
        {
            // if ticketNumber occurs once
            // set isUnique to true, otherwise false
        }
    }

Upvotes: 3

Views: 1054

Answers (4)

Asav Vora
Asav Vora

Reputation: 71

It can be done in single Linq.

Tickets.GroupBy(grptckt => grptckt.TicketNumber)
       .Where(tckt => tckt.Count() == 1)
       .Select(val => val.FirstOrDefault().IsUnique = true)
       .ToList();

GroupBy: Grouping tickets with ticket number. Where: Check Ticket Number is not repeating with checking count in grouping. Select: Select unique Ticket and update isUnique to true. ToList: Update Existing list with changes into same list.

Upvotes: 0

Seva
Seva

Reputation: 1739

I'd do something like this:

tickets.GroupBy(t => t.TicketNumber)
    .Where(g => g.Count() == 1)
    .ForEach(g => g.ForEach(t => t.IsUnique = true));

I'd need this extension method to enable the .ForEach() syntax though:

public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
    foreach (var item in enumerable)
    {
        action(item);
    }
}

Upvotes: 0

Marco
Marco

Reputation: 23927

Since I've neglected the code comment // set isUnique to true, otherwise false Magnus answer is to be preferred.

  1. Group by ticket number / id
  2. Filter out those groups with multiple items
  3. Flatten the results back
  4. The resulting collection is those items, which are unique by its number
public void UpdateTickets(IList<Ticket> tickets)
{
    var uniqueTickets = tickets.GroupBy (t => t.TicketNumber)
        .Where (t => t.Count () == 1)
        .SelectMany (t => t);

    foreach (var ticket in uniqueTickets)
    {
        ticket.IsUnique = true;
    }
}

Fiddle: https://dotnetfiddle.net/EgICJr

Upvotes: 3

Magnus
Magnus

Reputation: 46909

This should do it:

foreach (var g in tickets.GroupBy(x => x.TicketNumber))
{
    var unique = !g.Skip(1).Any();
    foreach (var ticket in g)
    {
        ticket.IsUnique = unique;
    }
}

We group tickets with the same number together and than we check of there are more than 1 item in the group.

Upvotes: 5

Related Questions