Adrian
Adrian

Reputation: 13

C# Grouping a sorted List by following value

I have a sorted "List orders". The list is already ordered and looks like this:

class Order {
public int Id { get; set; }
public string Name { get; set; }
public string DeliveryPerson { get; set; }
}

They are already sorted by Id:

Order12 [DeliveryPerson: Andrea]
Order13 [DeliveryPerson: David]
Order14 [DeliveryPerson: Andrea]
Order15 [DeliveryPerson: Andrea]
Order16 [DeliveryPerson: Linda]
...

Now I want to group them by DeliveryPerson BUT depending on the following Id: --> so Order12 is one group, Order 13 is one group but Order 14 and 15 are in one group together because from perspective of Order14, Order 15 has the same DeliveryPerson. (Order16 is a new group again)

How do I do that? Do I still have to work with lists or IEnumerables or ...? Hope someone can help me.

Upvotes: 1

Views: 213

Answers (2)

Mohammadreza Askari
Mohammadreza Askari

Reputation: 583

this extension might be helpful for you, be my guest ;)

    public static IEnumerable<IGrouping<TKey, TElement>> GroupByFollowingValue<TKey, TElement>(
        this IEnumerable<TElement> elements, Func<TElement, TKey> keySelector)
    {
        IEnumerable<IGrouping<TKey, TElement>> o = null;
        for (int i = 0; i < elements.Count();)
        {
            int s = i;
            var ts = elements.Skip(s).TakeWhile(x => keySelector.Invoke(x).Equals(elements.Select(keySelector).ElementAt(s)));
            i += ts.Count();
            if (o != null) o = o.Concat(ts.GroupBy(keySelector));
            else o = ts.GroupBy(keySelector);
        }
#if DEBUG
        foreach (var t in o)
        {
            Console.WriteLine($"\r\n{t.Key}");
            foreach (var i in t) { Console.Write($"\t{i}"); }
        } 
#endif
        return o;
    }

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460058

You want kind of consecutive grouping? You can use the following loop:

List<Order> orders = // your list

List<List<Order>> orderGroups = new List<List<Order>>();
if(orders.Count > 0) orderGroups.Add(new List<Order> { orders[0] });

for (int i = 1; i < orders.Count; i++)
{
    Order currentOrder = orders[i];
    if (orders[i - 1].DeliveryPerson != currentOrder.DeliveryPerson)
        orderGroups.Add(new List<Order> { currentOrder });
    else
        orderGroups.Last().Add(currentOrder);
}

Upvotes: 1

Related Questions