C#列出分组并分配值

时间:2014-01-03 09:47:52

标签: c# linq

我有一份订单清单。此列表包含同一项目的多个订单,请参阅下表。

然后,我想为每个相同的项目(即ABC)分配相同的块ID。所以ABC的块ID为1&每个GHJ的块ID为2等。这样做的最佳方法是什么?

目前我按订单ID订购列表,然后有一个for循环并检查当前订单ID是否等于下一个订单ID,如果是这样,则为这两个订单ID分配相同的块ID。有没有更好的方法来使用linq或任何其他方法?

Order ID             Block ID

ABC 
ABC
ABC
GHJ
GHJ
GHJ
MNO
MNO

2 个答案:

答案 0 :(得分:2)

你可以这样做,它会为同一个orderid分配相同的blockid

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

它将按orderid对订单进行分组,然后为每个组分配下一个blockid。请注意,它不会在linq中完全完成,因为linq用于查询而不更改数据。

答案 1 :(得分:1)

在此上下文中,始终取决于更好对您意味着什么。

这个琐碎的问题有很多可能的解决方案 在我的头顶,我能想到:

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

或( 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;
    }
}

或(你还能按照代码吗?):

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;
}

或(可能最接近简单的for循环):

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的?是的。
比简单的循环好吗? Uhmmmm ....


使用Linq不会神奇地使您的代码更好。当然,它可以使它通常更具说明性/可读性/更快(就懒惰评估而言),但是如果你试图强迫使用Linq,你肯定可以制作其他精细的命令循环不可读 LINQ。


作为旁注:
如果您想获得有关工作代码的反馈,可以在codereview.stackexchange.com

询问