我有两个阵列..
var data1 = new[] {
new { Product = "Product 1", Year = 2009, Sales = 1212 },
new { Product = "Product 2", Year = 2009, Sales = 522 },
new { Product = "Product 1", Year = 2010, Sales = 1337 },
new { Product = "Product 2", Year = 2011, Sales = 711 },
new { Product = "Product 2", Year = 2012, Sales = 2245 },
new { Product = "Product 3", Year = 2012, Sales = 1000 }
};
var data2 = new[] {
new { Product = "Product 1", Year = 2009, Sales = 1212 },
new { Product = "Product 1", Year = 2010, Sales = 1337 },
new { Product = "Product 2", Year = 2011, Sales = 711 },
new { Product = "Product 2", Year = 2012, Sales = 2245 }
};
我希望按data1
对Product
进行分组,并按Sales
对data2
中存在的那些产品进行分组,并按相同方式排序因为他们在data2
。请注意,即使data2
中存在某个产品,data1
中data2
中的所有年份都不会出现在{ Product = "Product 2", Year = 2009, Sales = 522 }
中(例如data1
),因此分组并且总和必须在data1.GroupBy(x=>x.Product)
.Select(x=>new {Product=x.Key,Total= x.Sum(s=>s.Sales)})
上发生。
要进行分组并总结以下应该有效..
Product
但我如何确保我只选择data2中的产品并按{{1}}排序结果,如data2
答案 0 :(得分:1)
您需要做两件事:首先,您从data2
中选择可用的产品。为此,您可以使用Select
的重载,它也会给出匹配元素的索引。
其次,您根据data1
中的产品过滤了data2
,然后执行分组。最后一步,添加一个与CorrespondingIndex
中产品索引相匹配的新属性data2
。此索引可用于根据data1
中产品的排序对您的data2
列表进行排序。
var productsWithIndex = data2
.Select(x => x.Product)
.Distinct()
.Select((p, idx) => new {Product = p, Index = idx});
var filteredProducts = data1
.Where(x => productsWithIndex.Select(p => p.Product).Contains(x.Product))
.GroupBy(x => x.Product)
.Select(x => new
{
Product = x.Key,
Total = x.Sum(s => s.Sales),
CorrespondingIndex = productsWithIndex.Single(p => p.Product == x.Key).Index
})
.OrderBy(x => x.CorrespondingIndex);
答案 1 :(得分:1)
我会采取不同的方法。
由于您希望最终结果以相同的顺序包含第二个列表中的产品,因此我首先从第二个列表中获取Distinct
个产品。
虽然文档中没有明确说明,但Distinct
方法(类似于GroupBy
)按照源中唯一元素第一次出现的顺序生成不同的元素,因此结果为Distinct
将是正确顺序的最终结果的产品。
然后我会使用GroupJoin
将它与第一个列表相关联,最后得到一个非常有效的查询:
var result = data2.Select(item => item.Product).Distinct()
.GroupJoin(data1, product => product, item => item.Product, (product, group) =>
new { Product = product, Sales = group.Sum(item => item.Sales) })
.ToList();
答案 2 :(得分:0)
如果用户1384848去了,你甚至不需要详细介绍。 你可能会得到更简单的东西:
var result =
data1.Where(e => data2.Any(x => x.Product == e.Product))
.GroupBy(arg => arg.Product,
(name, products) => new {Product = name, Total = products.Sum(e => e.Sales)})
.OrderBy(d => d.Product);