C# C LINQ-如何申请分组?

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)

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

    }

要仅报告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 );
    }
}