tags:

views:

183

answers:

4

I am new to linq.From the list of following data,help me how can i apply Group by and other construct to achieve the expected output as given below.

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

    }

conditions :

1) Report only needed for the year 2008 and 2009 only

2) Numberofunits >=30000 are Top Movement products

3) Numberofunits >=10000 to < 30000 are average movement products

4) Numberofunits <10000 are poor moving product

Expected output:

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
+10  A: 

To report only items for 2008 and 2009, use a where clause:

where sa.Year == 2008 || sa.Year == 2009

For the rest, I would suggest an enum to classify the "band":

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

You can then do:

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

That produces the output you were after, modulo ordering and formatting.

Jon Skeet
+2  A: 
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);
    }
}
Marc Gravell
+2  A: 
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.
mquander
+2  A: 

Try:

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