LINQ 合并行中的结果

发布于 2024-08-12 03:25:04 字数 354 浏览 5 评论 0原文

我有一个返回一组行的 LINQ 查询。结构是:

NAME,    col1, col2, col3, col4
name1     1    null  null  null
name1    null   1    null  null
name1    null  null   1     1 

因此,我想要一行包含

name1     1     1     1     1

所以我想按名称对这些结果进行分组并合并(求和?)其他列,因此如果我在一列中的某一行中没有 null - 我将收到除 null 之外的任何内容。

感谢您的帮助!

I have a LINQ query which returns a set of rows. The structure is:

NAME,    col1, col2, col3, col4
name1     1    null  null  null
name1    null   1    null  null
name1    null  null   1     1 

As a result I want to have one row containing

name1     1     1     1     1

So I want to group those results by name and merge (sum?) the other columns so if I have not null in one of the rows in a column - I will receive anything except null.

Thanks for help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青瓷清茶倾城歌 2024-08-19 03:25:04
class MyObj
{
    public string Name { get; set; }
    public int? Col1 { get; set; }
    public int? Col2 { get; set; }
    public int? Col3 { get; set; }
    public int? Col4 { get; set; }
}

List<MyObj> l = new List<MyObj> {
    new MyObj {Name = "name1", Col1 = 1 },
    new MyObj {Name = "name1", Col2 = 1 },
    new MyObj {Name = "name1", Col3 = 1 },
    new MyObj {Name = "name1", Col4 = 1 }
};

var qry = from o in l
          group o by o.Name into g
          select new
          {
              Name = g.Key,
              Col1 = g.Any(e => e.Col1.HasValue) ? (int?)1 : null,
              Col2 = g.Any(e => e.Col2.HasValue) ? (int?)1 : null,
              Col3 = g.Any(e => e.Col3.HasValue) ? (int?)1 : null,
              Col4 = g.Any(e => e.Col4.HasValue) ? (int?)1 : null
          };
class MyObj
{
    public string Name { get; set; }
    public int? Col1 { get; set; }
    public int? Col2 { get; set; }
    public int? Col3 { get; set; }
    public int? Col4 { get; set; }
}

List<MyObj> l = new List<MyObj> {
    new MyObj {Name = "name1", Col1 = 1 },
    new MyObj {Name = "name1", Col2 = 1 },
    new MyObj {Name = "name1", Col3 = 1 },
    new MyObj {Name = "name1", Col4 = 1 }
};

var qry = from o in l
          group o by o.Name into g
          select new
          {
              Name = g.Key,
              Col1 = g.Any(e => e.Col1.HasValue) ? (int?)1 : null,
              Col2 = g.Any(e => e.Col2.HasValue) ? (int?)1 : null,
              Col3 = g.Any(e => e.Col3.HasValue) ? (int?)1 : null,
              Col4 = g.Any(e => e.Col4.HasValue) ? (int?)1 : null
          };
半夏半凉 2024-08-19 03:25:04
public class AggregateRows
{
    class AA { public string A, B, C, D;}

    public void DoIt()
    {
        List<AA> a = new List<AA>(  ) 
        {
            new AA { A="1", B=null, C=null, D=null},
            new AA { A=null, B="1", C=null, D=null},
            new AA { A=null, B=null, C="1", D=null},
            new AA { A=null, B=null, C=null, D="1"},
        };

        var result = a.Aggregate( ( a1, a2 ) => new AA { A = a1.A ?? a2.A, B = a1.B ?? a2.B, C = a1.C ?? a2.C, D = a1.D ?? a2.D } );
        Console.WriteLine("{0}{1}{2}{3}",result.A,result.B,result.C,result.D);
    }
}

产量

1111

public class AggregateRows
{
    class AA
    {
        public string N, A, B, C, D;
    }

    public void DoIt()
    {
        List<AA> data = new List<AA>() 
        {
            new AA { N="Name", A="1", B=null, C=null, D=null},
            new AA { N="Name", A=null, B="2", C=null, D=null},
            new AA { N="Name", A=null, B=null, C="3", D=null},
            new AA { N="Name", A=null, B=null, C=null, D="4"},
            new AA { N="Name2", A="2", B=null, C=null, D=null},
            new AA { N="Name2", A=null, B="2", C=null, D=null},
            new AA { N="Name2", A=null, B=null, C="2", D=null},
            new AA { N="Name2", A=null, B=null, C=null, D="2"},
        };

        var results = data.GroupBy( a => a.N )
            .Select( k =>
            {
                var values = k.Aggregate( ( a1, a2 ) => new AA
                {
                    A = a1.A ?? a2.A,
                    B = a1.B ?? a2.B,
                    C = a1.C ?? a2.C,
                    D = a1.D ?? a2.D
                } );
                return new AA { N = k.Key, A = values.A, B = values.B, C = values.C, D = values.D };
            } );
        foreach ( var result in results )
            Console.WriteLine( "{0} {1}{2}{3}{4}", result.N, result.A, result.B, result.C, result.D );
    }
}

产量

Name 1234
Name2 2222

编辑:为了回应您的澄清...

我想您将能够从这里获取它。如果您想要做的只是找出组内是否有列,那么像 Bruno 的答案中那样的 Any 运算符就是正确的选择。仅当您尝试实际访问所有值以便执行更复杂的操作(例如对它们求和)时,才需要聚合(尽管正如 Jon 提到的,Sum 处理特定的值)案件)。

简而言之,您想要的是像在两个答案中一样进行分组,然后在组中您可以使用 Aggregate 逐行合并,或者在结果上使用多个 Any GroupBy 取决于哪个在您的上下文中更清晰(或者如果每个组中有大量数据,则效率更高)

public class AggregateRows
{
    class AA { public string A, B, C, D;}

    public void DoIt()
    {
        List<AA> a = new List<AA>(  ) 
        {
            new AA { A="1", B=null, C=null, D=null},
            new AA { A=null, B="1", C=null, D=null},
            new AA { A=null, B=null, C="1", D=null},
            new AA { A=null, B=null, C=null, D="1"},
        };

        var result = a.Aggregate( ( a1, a2 ) => new AA { A = a1.A ?? a2.A, B = a1.B ?? a2.B, C = a1.C ?? a2.C, D = a1.D ?? a2.D } );
        Console.WriteLine("{0}{1}{2}{3}",result.A,result.B,result.C,result.D);
    }
}

yields

1111

and

public class AggregateRows
{
    class AA
    {
        public string N, A, B, C, D;
    }

    public void DoIt()
    {
        List<AA> data = new List<AA>() 
        {
            new AA { N="Name", A="1", B=null, C=null, D=null},
            new AA { N="Name", A=null, B="2", C=null, D=null},
            new AA { N="Name", A=null, B=null, C="3", D=null},
            new AA { N="Name", A=null, B=null, C=null, D="4"},
            new AA { N="Name2", A="2", B=null, C=null, D=null},
            new AA { N="Name2", A=null, B="2", C=null, D=null},
            new AA { N="Name2", A=null, B=null, C="2", D=null},
            new AA { N="Name2", A=null, B=null, C=null, D="2"},
        };

        var results = data.GroupBy( a => a.N )
            .Select( k =>
            {
                var values = k.Aggregate( ( a1, a2 ) => new AA
                {
                    A = a1.A ?? a2.A,
                    B = a1.B ?? a2.B,
                    C = a1.C ?? a2.C,
                    D = a1.D ?? a2.D
                } );
                return new AA { N = k.Key, A = values.A, B = values.B, C = values.C, D = values.D };
            } );
        foreach ( var result in results )
            Console.WriteLine( "{0} {1}{2}{3}{4}", result.N, result.A, result.B, result.C, result.D );
    }
}

yields

Name 1234
Name2 2222

EDIT: In response to your clarification...

I guess you'll be able to take it from here then. If all you want to do is find out whether there is a column within the group, then the Any operator like in Bruno's answer is the way to go. Aggregate is only necessary if you're trying to actually visit all the values in order to do something more complex like summing them (although as Jon alluded to, Sum handles that specific case).

In short, what you want is grouping like in both the answer, and then within the group you either use Aggregate to merge row by row or multiple Any on the results of the GroupBy depending on which is clearer in your context (or more efficient if you have a large set of data within each group)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文