2009-12-01 64 views
2

我是linq的新手。從下面的數據列表中,幫助我如何應用Group by和 其他構造來實現如下所示的預期輸出。C#LINQ - 如何應用group?

 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> = 30000是頂級機芯產品

3)Numberofunits> = 10000 < 30000是平均運動產品

4)單元數量< 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

我是誰讀 「Analist」 的頁面上的第一件事情唯一的一個!? – cwap 2009-12-01 20:04:59

+2

您的銷售數據已經分組 - 看起來您需要Where和OrderBy? – 2009-12-01 20:05:27

回答

10

要爲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(); 
} 

產生你之後的輸出,模排序和格式化。

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
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. 
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); 
    } 
}