我正在尝试按2个字段(类别,然后是供应商)对列表进行分组,但是值不同。如果类别为“01”,则将所有成本加起来。如果类别不是“01”,则按类别分组,然后按供应商分组。
一些演示数据:
List<MyItem> myItemList = new List<MyItem>();
myItemList.Add(new MyItem{Vendor="Ven1", Cost=100, Category="01"});
myItemList.Add(new MyItem{Vendor="Ven2", Cost=10, Category="02"});
myItemList.Add(new MyItem{Vendor="Ven3", Cost=50, Category="02"}));
myItemList.Add(new MyItem{Vendor="Ven2", Cost=40, Category="01"});
myItemList.Add(new MyItem{Vendor="Ven2", Cost=20, Category="01"});
myItemList.Add(new MyItem{Vendor="Ven3", Cost=30, Category="02"});
myItemList.Add(new MyItem{Vendor="Ven1", Cost=10, Category="03"});
我目前正在做的事情:
List<MyItem> groupedItems = myItemList.GroupBy(a=> new {a.Category, a.Vendor})
.Select(b=> new MyItem{
Vendor = b.First().Vendor,
Cost = b.Sum(c => c.Cost),
Category = b.First().Category
}).ToList();
我想做什么(也就是我最好的猜测):
List<MyItem> groupedItems = myItemList.GroupBy(a=> new {a.Category.Where(z=>z.Category.Equals("01:)), a.Vendor})
.Select(b=> new MyItem{
Vendor = b.First().Vendor,
Cost = b.Sum(c => c.Cost),
Category = b.First().Category
}).ToList();
期望的结果:
Category = "01", Vendor = "N/A ", Cost = 160
Category = "02", Vendor = "Ven2", Cost = 10
Category = "02", Vendor = "Ven3", Cost = 80
Category = "03", Vendor = "Ven1", Cost = 10
答案 0 :(得分:4)
GroupBy
返回一个包含2个字段的匿名类型。返回对象内的值可以是任何值。在这种情况下,如果类别为&#34; 01&#34;:myItemList.GroupBy(a=> new {a.Category, Vendor= a.Category == "01" ? null : a.Vendor})
可以更改它们为了与当前代码保持一致,该属性名为Vendor,但可以是任何名称。
在您当前的代码中:
List<MyItem> groupedItems = myItemList
.GroupBy(a => new {a.Category, Vendor = a.Category == "01" ? null : a.Vendor})
.Select(b => new MyItem
{
Vendor = b.First().Vendor,
Cost = b.Sum(c => c.Cost),
Category = b.First().Category
})
.ToList();
或稍微改动,而不是组的First()
值,您可以重复使用密钥(并一次性实施N\A
)
List<MyItem> groupedItems = myItemList
.GroupBy(a=> new {a.Category, Vendor= a.Category == "01" ? "N/A" : a.Vendor})
.Select(b=> new MyItem{
Vendor = b.Key.Vendor,
Cost = b.Sum(c => c.Cost),
Category = b.Key.Category
}).ToList();
答案 1 :(得分:0)
暂时我想创建两个单独的查询:
List<MyItem> groupedItemsByCat01 = myItemList.Where(z => z.Category.Equals("01"))
.GroupBy(a => a.Category)
.Select(b=> new MyItem{
Vendor = "N/A",
Cost = b.Sum(c => c.Cost),
Category = b.First().Category
}).ToList();
List<MyItem> groupedItemsByOther = myItemList.Where(z => !z.Category.Equals("01"))
.GroupBy(a => new {a.Category, a.Vendor})
.Select(b=> new MyItem{
Vendor = b.First().Vendor,
Cost = b.Sum(c => c.Cost),
Category = b.First().Category
}).ToList();
List<MyItem> final = new List<MyItem>();
final.AddRange(groupedItemsByCat01);
final.AddRange(groupedItemsByOther);
答案 2 :(得分:0)
在一个Linq-Expression中执行此操作有点棘手:
var newList = myItemList
.Where(item => item.Category != "01")
.GroupBy(item => new {item.Category, item.Vendor})
.Select(group => new MyItem()
{
Vendor = group.Key.Vendor,
Category = group.Key.Category,
Cost = group.Sum(item => item.Cost)
})
.Union(new[]
{
new MyItem()
{
Vendor = "N/A",
Category = "01",
Cost = myItemList.Where(item => item.Category == "01").Sum(item => item.Cost)
}
});
foreach (var loItem in newList)
{
Debug.WriteLine("Category = {0}, Vendor = {1}, Cost = {2}",
loItem.Category, loItem.Vendor, loItem.Cost);
}