C# List grouping and assigning a value

前端 未结 2 421
花落未央
花落未央 2021-01-24 06:26

I have a list of Orders. This list contains multiple orders for the same item, see the table below.

I then want to assign each item that is the same (i.e. ABC) the same

相关标签:
2条回答
  • 2021-01-24 06:58

    Always depends of what better means for you in this context.

    There are a bunch of possible solutions to this trivial problem.
    On top of my head, I could think of:

    var blockId = 1;
    foreach(var grp in yourOrders.GroupBy(o => o.OrderId))
    {
        foreach(var order in grp)
        {
            order.BlockId = blockId;
        }
        blockId++;
    }
    

    or (be more "linqy"):

    foreach(var t in yourOrders.GroupBy(o => o.OrderId).Zip(Enumerable.Range(1, Int32.MaxValue), (grp, bid) => new {grp, bid}))
    {
        foreach(var order in t.grp)
        {
            order.BlockId = t.bid;
        }
    }
    

    or (can you still follow the code?):

    var orders = yourOrders.GroupBy(o => o.OrderId)
                           .Zip(Enumerable.Range(1, Int16.MaxValue), (grp, id) => new {orders = grp, id})
                           .SelectMany(grp => grp.orders, (grp, order) => new {order, grp.id});
    foreach(var item in orders)
    {
        item.order.BlockId = item.id;
    }
    

    or (probably the closest to a simple for loop):

    Order prev = null;
    blockId = 1;
    foreach (var order in yourOrders.OrderBy(o => o.OrderId))
    {
        order.BlockId = (prev == null || prev.OrderId == order.OrderId) ?
                        blockId :
                        ++blockId;
        prev = order;
    }
    

    Linq? Yes.
    Better than a simple loop? Uhmmmm....


    Using Linq will not magically make your code better. Surely, it can make it often more declarative/readable/faster (in terms of lazy evaluation), but sure enough you can make otherwise fine imperative loops unreadable if you try to force the use of Linq just because Linq.


    As a side note:
    if you want to have feedback on working code, you can ask at codereview.stackexchange.com

    0 讨论(0)
  • 2021-01-24 06:58

    You can do this that way, it will assign same blockid for same orderid

    var ordered = listOrder.GroupBy(x => x.OrderId).ToList();
    for (int i = 0; i < ordered.Count(); i++)
    {
        ordered[i].ForEach(x=>x.BlockId=i+1);
    }   
    

    it will group orders by orderid then assign each group next blockid. Note that it won't be done fully in linq, because linq is for querying not changing data.

    0 讨论(0)
提交回复
热议问题