使用LINQ在C#中汇总数据

时间:2014-12-01 10:35:33

标签: c# linq

我是LINQ的新手并试图聚合一些数据。 我的数据格式如下

CURRENCY PRODUCT LEVEL1 LEVEL2  VALUE

USDJPY  OPTION  100 0.2 10000

USDJPY  FWD 100 0.2 3000

USDJPY  OPTION  100 0.2 2000

USDJPY  FWD 100 0.2 1000

USDJPY  OPTION  101 0.2 10000

USDJPY  FWD 101 0.2 3000

USDJPY  OPTION  101 0.2 2000

USDJPY  FWD 101 0.2 1000

USDJPY  OPTION  100 0.3 10000

USDJPY  FWD 100 0.3 3000

USDJPY  OPTION  100 0.3 2000

USDJPY  FWD 100 0.3 1000

USDJPY  OPTION  101 0.3 10000

USDJPY  FWD 101 0.3 3000

USDJPY  OPTION  101 0.3 2000

USDJPY  FWD 101 0.3 1000

USDJPY  OPTION  100 0.2 2000

USDJPY  FWD 100 0.2 5000

USDJPY  OPTION  100 0.2 7000

USDJPY  FWD 100 0.2 9000

USDJPY  OPTION  101 0.2 2000

USDJPY  FWD 101 0.2 1000

USDJPY  OPTION  101 0.2 2000

USDJPY  FWD 101 0.2 5000

USDJPY  OPTION  100 0.3 7000

USDJPY  FWD 100 0.3 9000

USDJPY  OPTION  100 0.3 2000

USDJPY  FWD 100 0.3 1000

USDJPY  OPTION  101 0.3 2000

USDJPY  FWD 101 0.3 5000

USDJPY  OPTION  101 0.3 7000

USDJPY  FWD 101 0.3 9000

我想通过LEVEL1和LEVEL2以及PRODUCT总结这些数据中的VALUE。 因此,在对预期结果进行分组和总结之后,如下所示。

CURRENCY  PRODUCT   LEVEL1  LEVEL2  VALUE

USDJPY  OPTION  100 0.2 21000

USDJPY  OPTION  101 0.2 16000

USDJPY  FWD 100 0.2 18000

USDJPY  FWD 101 0.2 10000

USDJPY  OPTION  100 0.3 21000

USDJPY  OPTION  101 0.3 21000

USDJPY  FWD 100 0.3 14000

USDJPY  FWD 101 0.3 18000

基本上,对于product,level1和level2的每个组合,结果应该只有一行或一个对象,value应该是值的总和。 结果数据应与初始数据位于相同的结构(或相同的列)中。 我尝试过使用group by和Sum但是没能正确使用它。

有人可以帮我解决C#中的LINQ操作,以获得此结果。

我将这些数据存储为以下类的对象列表:

public class RiskData
{

    public string CcyPair { get; set; }
    public string Product { get; set; }

    public string SpotLvl { get; set; }
    public string VolLvl  { get; set; }
    public double Risk { get; set; }

    public RiskData(string ccypair, string product, string spotlvl, string vollvl, double risk)
    {
        CcyPair = ccypair;
        Product = product;
        SpotLvl = spotlvl;
        VolLvl = vollvl;
        Risk = risk;

    }

}
 var result = from data in riskdata
                     group by data.SpotLvl
                     select new RiskData(???)

提前致谢。

1 个答案:

答案 0 :(得分:1)

您缺少的语言构造使用匿名类型作为组密钥:

   var result = risksObjects.GroupBy(g => new { g.Product, g.Level1, g.Level2 } )
                    .Select(
                        g => new { 
                            Key = g.Key,
                            Total = g.Sum(r => r.Risk)
                        }
                    )
                    .ToArray();

完整代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication13
{

public class RiskData { 
     public string CcyPair { get; set; } 
     public string Product { get; set; } 
     public string SpotLvl { get; set; } 
     public string VolLvl { get; set; } 
     public double Risk { get; set; }

     public double Level1
     {
         get
         {
             double result;
             if (double.TryParse(SpotLvl, out result))
                 return result;
             else
                 return 0;
         }
     }

     public double Level2
     {
         get
         {
             double result;
             if (double.TryParse(VolLvl, out result))
                 return result;
             else
                 return 0;
         }
     }

     public RiskData(string ccypair, string product, string spotlvl, string vollvl, double risk)
     {
         CcyPair = ccypair;
         Product = product;
         SpotLvl = spotlvl;
         VolLvl = vollvl;
         Risk = risk;
     }
}



    class Program
    {
        static void Main(string[] args)
        {

            List<RiskData> risksObjects = Load();





        var result = risksObjects.GroupBy(g => new { g.Product, g.Level1, g.Level2 } )
                        .Select(
                            g => new { 
                                Key = g.Key,
                                Total = g.Sum(r => r.Risk)
                            }
                        )
                        .ToArray();


        foreach (var r in result)
            Console.WriteLine("Key: " + r.Key + ", Total: " + r.Total);


            Console.ReadLine();

        }

        static List<RiskData> Load()
        {
            var result = new List<RiskData>();

//            INSTRUMENT  PORTFOLIO   PRODUCT LEVEL1  LEVEL2  VALUE

result.Add(new RiskData("USDJPY","OPTION","100", "0.2",10000));
result.Add(new RiskData("USDJPY","FWD","100", "0.2",3000));

// just copy/pasted the above two lines a bunch in here...

result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));
result.Add(new RiskData("USDJPY", "OPTION", "100", "0.2", 10000));
result.Add(new RiskData("USDJPY", "FWD", "100", "0.2", 3000));



            return result;
        }
    }
}