C# C LINQ-如何申请分组?
我是linq的新手。从以下数据列表中,请帮助我如何申请Group by和 实现预期输出的其他构造,如下所示C# C LINQ-如何申请分组?,c#,linq,C#,Linq,我是linq的新手。从以下数据列表中,请帮助我如何申请Group by和 实现预期输出的其他构造,如下所示 List<SalesAnalysis> AnaList = new List<SalesAnalysis>(); AnaList.Add(new SalesAnalysis("P001", 2009, 45000)); AnaList.Add(new SalesAnalysis("P001", 2008, 13000)
List<SalesAnalysis> AnaList = new List<SalesAnalysis>();
AnaList.Add(new SalesAnalysis("P001", 2009, 45000));
AnaList.Add(new SalesAnalysis("P001", 2008, 13000));
AnaList.Add(new SalesAnalysis("P002", 2009, 5000));
AnaList.Add(new SalesAnalysis("P002", 2008, 15000));
AnaList.Add(new SalesAnalysis("P003", 2009, 25000));
AnaList.Add(new SalesAnalysis("P003", 2008, 65000));
AnaList.Add(new SalesAnalysis("P004", 2009, 5000));
AnaList.Add(new SalesAnalysis("P004", 2008, 3000));
AnaList.Add(new SalesAnalysis("P004", 2007, 95000));
AnaList.Add(new SalesAnalysis("P004", 2006, 83000));
class SalesAnalysis
{
public string ProductCode
{
get;
set;
}
public int Year
{
get;
set;
}
public int NumberOfUnitsSold
{
get;
set;
}
public SalesAnalysis(string productcode, int year,
int numberofunitssold)
{
ProductCode = productcode;
Year = year;
NumberOfUnitsSold = numberofunitssold;
}
}
要仅报告2008年和2009年的项目,请使用where子句:
where sa.Year == 2008 || sa.Year == 2009
对于其余部分,我建议使用枚举对波段进行分类:
public enum Movement
{
Top,
Average,
Poor
}
public static Movement MovementForAnalysis(SalesAnalysis sa)
{
return sa.NumberOfUnitsSold >= 30000 ? Movement.Top
: sa.NumberOfUnitsSold >= 10000 ? Movement.Average
: Movement.Poor;
}
然后,您可以执行以下操作:
var query = from sa in AnaList
where sa.Year == 2008 || sa.Year == 2009
group sa by MovementForAnalysis(sa);
foreach (var group in query)
{
Console.WriteLine("{0}: ", group.Key);
foreach (var item in group)
{
Console.WriteLine("{0} / {1} / {2}", item.ProductCode,
item.Year, item.NumberOfUnitsSold);
}
Console.WriteLine();
}
这将生成您想要的输出,按模数排序和格式设置。尝试:
Show(AnaList, 30000, int.MaxValue, "Top Movement");
Show(AnaList, 10000, 30000, "Average Movement");
Show(AnaList, 0, 10000, "Poor Movement");
static void Show(IEnumerable<SalesAnalysis> data, int min, int max, string caption)
{
int[] years = {2008,2009};
var qry = from row in data
where years.Contains(row.Year)
&& row.NumberOfUnitsSold >= min
&& row.NumberOfUnitsSold < max
orderby row.NumberOfUnitsSold descending
select row;
Console.WriteLine(caption);
Console.WriteLine();
Console.WriteLine("Product\tYear\tUnits");
foreach(var row in qry) {
Console.WriteLine("{0}\t{1}\t{2}",
row.ProductCode, row.Year, row.NumberOfUnitsSold);
}
}
我是唯一一个把《分析论》作为第一件事读的人吗!?您的销售数据看起来已经分组了-看起来您需要Where和OrderBy?
Show(AnaList, 30000, int.MaxValue, "Top Movement");
Show(AnaList, 10000, 30000, "Average Movement");
Show(AnaList, 0, 10000, "Poor Movement");
static void Show(IEnumerable<SalesAnalysis> data, int min, int max, string caption)
{
int[] years = {2008,2009};
var qry = from row in data
where years.Contains(row.Year)
&& row.NumberOfUnitsSold >= min
&& row.NumberOfUnitsSold < max
orderby row.NumberOfUnitsSold descending
select row;
Console.WriteLine(caption);
Console.WriteLine();
Console.WriteLine("Product\tYear\tUnits");
foreach(var row in qry) {
Console.WriteLine("{0}\t{1}\t{2}",
row.ProductCode, row.Year, row.NumberOfUnitsSold);
}
}
private enum Measure { Top, Average, Poor }
private Measure Classify(int nUnits)
{
if (nUnits >= 30000) return Measure.Top;
else if (nUnits >= 10000) return Measure.Average;
else return Measure.Poor;
}
/* ... */
var years = new int[] { 2008, 2009 };
var salesByMeasure =
AnaList.Where(a => years.Contains(a.Year))
.ToLookup(a => Classify(a.NumberOfUnitsSold));
var topSales = salesByMeasure[Measure.Top]; // e.g.
var groups = anaList.Where( p => p.Year > 2007 ); // limit year scope
.GroupBy( g => g.NumberOfUnitsSold > 30000
? "Top"
: (g.NumberOfUnitSold >= 10000
? "Average"
: "Poor" );
foreach (var group in groups)
{
Console.WriteLine( "{0} Movement", group.Key );
foreach (var product in group.OrderByDescending( p => p.NumberOfUnitsSold ))
{
Console.WriteLine( "{0} {1} {2}", product.ProductCode, product.Year, product.NumberofUnitsSold );
}
}