C# 在C语言中旋转多列#

C# 在C语言中旋转多列#,c#,.net,linq,c#-4.0,pivot,C#,.net,Linq,C# 4.0,Pivot,我有一个C#对象列表,需要对其进行透视和变换。但我不知道如何达到预期的效果。下面的代码讨论结构、数据和期望的结果。我知道,我需要首先对数据进行分组,然后对其进行透视。但我对如何实现这一目标感到困惑 class Program { static void Main(string[] args) { List<Rev> revList = new List<Rev>(); Rev r = new Rev { Id = 1, Na

我有一个C#对象列表,需要对其进行透视和变换。但我不知道如何达到预期的效果。下面的代码讨论结构、数据和期望的结果。我知道,我需要首先对数据进行分组,然后对其进行透视。但我对如何实现这一目标感到困惑

class Program
{
    static void Main(string[] args)
    {
        List<Rev> revList = new List<Rev>();
        Rev r = new Rev { Id = 1, Name = "One", Rank = 1, Region = "Global", Revenue = 600 }; revList.Add(r);
        r = new Rev { Id = 1, Name = "One", Rank = 1, Region = "USA", Revenue = 100 }; revList.Add(r);
        r = new Rev { Id = 1, Name = "One", Rank = 1, Region = "Euro", Revenue = 200 }; revList.Add(r);
        r = new Rev { Id = 1, Name = "One", Rank = 1, Region = "APAC", Revenue = 300 }; revList.Add(r);

        r = new Rev { Id = 2, Name = "Two", Rank = 2, Region = "Global", Revenue = 500 }; revList.Add(r);
        r = new Rev { Id = 2, Name = "Two", Rank = 2, Region = "USA", Revenue = 100 }; revList.Add(r);
        r = new Rev { Id = 2, Name = "Two", Rank = 3, Region = "APAC", Revenue = 400 }; revList.Add(r);

        r = new Rev { Id = 3, Name = "Three", Rank = 2, Region = "Global", Revenue = 300 }; revList.Add(r);
        r = new Rev { Id = 3, Name = "Three", Rank = 2, Region = "USA", Revenue = 100 }; revList.Add(r);
        r = new Rev { Id = 3, Name = "Three", Rank = 3, Region = "Euro", Revenue = 200 }; revList.Add(r);

        //Should result in THIS IS THE HARD CODED RESULT WHICH TRANFORM FUNCTION SHOULD GENERATE
        List<RevExtended> resultList = new List<RevExtended>();
        RevExtended res = new RevExtended{Name = "One", Id = 1, APACRevenue = 300, ApacRank = 1, EuroRank = 1, EurpRevenue = 200, GlobalRank = 1, GlobalRevenue = 600, USARank = 1, USARevenue = 100};
        res = new RevExtended { Name = "Two", Id = 2, APACRevenue = 400, ApacRank = 3, GlobalRank = 2, GlobalRevenue = 500, USARank = 2, USARevenue = 100 };
        res = new RevExtended { Name = "Three", Id = 3, EuroRank = 3, EurpRevenue = 200, GlobalRank = 2, GlobalRevenue = 300, USARank = 2, USARevenue = 100 };
    }

    public List<RevExtended> Transform(List<Rev> revList)
    {
        List<RevExtended> resultList = new List<RevExtended>();

        var query = from rev in revList
                    group rev by rev.Id into revGroup


        return resultList;
    }
}

public class Rev
{
    public string Name { get; set; }
    public int Id { get; set; }
    public int? Revenue { get; set; }
    public int? Rank { get; set; }
    public string Region { get; set; }
}

public class RevExtended
{
    public string Name { get; set; }
    public int Id { get; set; }

    public int? GlobalRevenue { get; set; }
    public int? GlobalRank { get; set; }

    public int? USARevenue { get; set; }
    public int? USARank { get; set; }

    public int? EurpRevenue { get; set; }
    public int? EuroRank { get; set; }

    public int? APACRevenue { get; set; }
    public int? ApacRank { get; set; }
}
类程序
{
静态void Main(字符串[]参数)
{
List revList=新列表();
Rev r=new Rev{Id=1,Name=“One”,Rank=1,Region=“Global”,Revenue=600};revList.Add(r);
r=newrev{Id=1,Name=“One”,Rank=1,Region=“USA”,Revenue=100};revList.Add(r);
r=newrev{Id=1,Name=“One”,Rank=1,Region=“Euro”,Revenue=200};revList.Add(r);
r=newrev{Id=1,Name=“One”,Rank=1,Region=“APAC”,Revenue=300};revList.Add(r);
r=newrev{Id=2,Name=“Two”,Rank=2,Region=“Global”,Revenue=500};revList.Add(r);
r=newrev{Id=2,Name=“Two”,Rank=2,Region=“USA”,Revenue=100};revList.Add(r);
r=newrev{Id=2,Name=“Two”,Rank=3,Region=“APAC”,Revenue=400};revList.Add(r);
r=newrev{Id=3,Name=“Three”,Rank=2,Region=“Global”,Revenue=300};revList.Add(r);
r=newrev{Id=3,Name=“Three”,Rank=2,Region=“USA”,Revenue=100};revList.Add(r);
r=newrev{Id=3,Name=“三”,Rank=3,Region=“Euro”,Revenue=200};revList.Add(r);
//应导致这是Transform函数应生成的硬编码结果
列表结果列表=新列表();
RevExtended res=new RevExtended{Name=“One”,Id=1,APACREVENCE=300,ApacRank=1,EuroRank=1,EurpRevenue=200,GlobalRank=1,GlobalRank=600,USARank=1,USAREANCE=100};
res=new RevExtended{Name=“Two”,Id=2,APACRevenue=400,ApacRank=3,GlobalRank=2,GlobalRevenue=500,USARank=2,usavenue=100};
res=新的重新扩展{Name=“Three”,Id=3,EuroRank=3,EuroPrevenue=200,GlobalRank=2,GlobalRevenue=300,USARank=2,USARRevenue=100};
}
公共列表转换(列表revList)
{
列表结果列表=新列表();
var query=来自revList中的rev
按版本Id将版本分组为版本组
返回结果列表;
}
}
公共类修订版
{
公共字符串名称{get;set;}
公共int Id{get;set;}
公共整数?收入{get;set;}
公共整数?秩{get;set;}
公共字符串区域{get;set;}
}
公共类重新扩展
{
公共字符串名称{get;set;}
公共int Id{get;set;}
public int?GlobalRevenue{get;set;}
公共整数?全局秩{get;set;}
公共int?usavenue{get;set;}
公共int?USARank{get;set;}
公共整数?EurpRevenue{get;set;}
公共整数?EuroRank{get;set;}
公共int?APACRevenue{get;set;}
公共int{get;set;}
}

以下是您可以采取的一种方法:

var pivoted =
    from d in data
    group d by new { d.Id, d.Name } into region
    let g = region.SingleOrDefault(d => d.Region == "Global") ?? new Rev()
    let u = region.SingleOrDefault(d => d.Region == "USA") ?? new Rev()
    let e = region.SingleOrDefault(d => d.Region == "Euro") ?? new Rev()
    let a = region.SingleOrDefault(d => d.Region == "APAC") ?? new Rev()
    select new RevExtended
    {
        Id = region.Key.Id,
        Name = region.Key.Name,
        GlobalRevenue = g.Revenue,
        GlobalRank = g.Rank,
        UsaRevenue = u.Revenue,
        UsaRank = u.Rank,
        EuroRevenue = e.Revenue,
        EuroRank = e.Rank,
        ApacRevenue = a.Revenue,
        ApacRank = a.Rank,
    };
如果在没有区域的情况下需要
null
值,则需要更改模型以支持它们

public class RevExtended
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int? GlobalRank { get; set; }
    public int? GlobalRevenue { get; set; }

    public int? UsaRank { get; set; }
    public int? UsaRevenue { get; set; }

    public int? EuroRank { get; set; }
    public int? EuroRevenue { get; set; }

    public int? ApacRank { get; set; }
    public int? ApacRevenue { get; set; }
}

当您不使用C#6.0时

var pivoted =
    from x in revList.ToLookup(d => new { d.Id, d.Name })
    let g = x.SingleOrDefault(d => d.Region == "Global") ?? new Rev()
    let u = x.SingleOrDefault(d => d.Region == "USA") ?? new Rev()
    let e = x.SingleOrDefault(d => d.Region == "Euro") ?? new Rev()
    let a = x.SingleOrDefault(d => d.Region == "APAC") ?? new Rev()
    select new RevExtended
    {
        Id = x.Key.Id,
        Name = x.Key.Name,
        GlobalRevenue = g.Revenue == null ? null : g.Revenue,
        GlobalRank = g.Rank == null ? null : g.Rank,
        USARevenue = u.Revenue == null ? null : u.Revenue,
        USARank = u.Rank == null ? null : u.Rank,
        EuroRevenue = e.Revenue == null ? null: e.Revenue,
        EuroRank = e.Rank == null ? null : e.Rank,
        ApacRevenue = a.Revenue == null ? null : a.Revenue,
        ApacRank = a.Rank == null ? null : a.Rank,
    };

@OpenStack,根据接受答案的最后一部分,您有一个针对6.0之前C#用户的答案。你的例子并不完全正确。有两个问题:

  • 您的示例始终有一个Rev对象,因此对象引用 将永远不会为空
  • 如果您确实允许空值(正如预期的那样),那么赋值逻辑不会保护您不受空值的影响
以下是6.0之前的C#版本的公认答案:

var pivoted =
    from x in revList.ToLookup(d => new { d.Id, d.Name })
    let g = x.SingleOrDefault(d => d.Region == "Global") 
    let u = x.SingleOrDefault(d => d.Region == "USA")
    let e = x.SingleOrDefault(d => d.Region == "Euro")
    let a = x.SingleOrDefault(d => d.Region == "APAC")
    select new RevExtended
    {
        Id = x.Key.Id,
        Name = x.Key.Name,
        GlobalRevenue = g == null ? null : g.Revenue,
        GlobalRank = g == null ? null : g.Rank,
        USARevenue = u == null ? null : u.Revenue,
        USARank = u == null ? null : u.Rank,
        EuroRevenue = e == null ? null: e.Revenue,
        EuroRank = e == null ? null : e.Rank,
        ApacRevenue = a == null ? null : a.Revenue,
        ApacRank = a == null ? null : a.Rank,
    };    

如果您同意,您可以更新您的答案以使其正确(如果您愿意,请复制并粘贴我的答案),我将删除此答案。

感谢您的快速帮助。这太棒了。当排名或收入不适用于任何地区时,当前显示为0,如何将其设置为空?@OpenStack Remove
??新版本()
从所有
行开始,让
行,然后在
内选择
使用
g?.Revenue
g?.Rank
等。
var pivoted =
    from x in revList.ToLookup(d => new { d.Id, d.Name })
    let g = x.SingleOrDefault(d => d.Region == "Global") 
    let u = x.SingleOrDefault(d => d.Region == "USA")
    let e = x.SingleOrDefault(d => d.Region == "Euro")
    let a = x.SingleOrDefault(d => d.Region == "APAC")
    select new RevExtended
    {
        Id = x.Key.Id,
        Name = x.Key.Name,
        GlobalRevenue = g == null ? null : g.Revenue,
        GlobalRank = g == null ? null : g.Rank,
        USARevenue = u == null ? null : u.Revenue,
        USARank = u == null ? null : u.Rank,
        EuroRevenue = e == null ? null: e.Revenue,
        EuroRank = e == null ? null : e.Rank,
        ApacRevenue = a == null ? null : a.Revenue,
        ApacRank = a == null ? null : a.Rank,
    };