我是linq的新手。从以下数据列表中,帮助我如何应用Group by和 其他构造以实现预期的输出,如下所示。
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;
}
}
条件:
1)仅报告2008和2009年的报告
2)Numberofunits&gt; = 30000是Top Movement产品
3)Numberofunits&gt; = 10000到&lt; 30000是平均运动产品
4)Numberofunits&lt; 10000是不良移动产品
预期产出:
Top Movement
Product Code Year Numberofunits
P003 2008 65000
P001 2009 45000
Average Movement
Product Code Year Numberofunits
P003 2009 25000
P002 2008 15000
P001 2008 13000
Poor Movement
Product Code Year Numberofunits
P002 2009 5000
P004 2009 5000
P004 2008 3000
答案 0 :(得分:10)
要仅报告2008年和2009年的项目,请使用where子句:
where sa.Year == 2008 || sa.Year == 2009
对于其他人,我建议使用enum对“乐队”进行分类:
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();
}
产生你所追求的输出,模数排序和格式化。
答案 1 :(得分:2)
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);
}
}
答案 2 :(得分:2)
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.
答案 3 :(得分:2)
尝试:
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 );
}
}