LINQ Объединение результатов в строки

У меня есть запрос 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

Итак, я хочу сгруппировать эти результаты по имени и объединить (суммировать?) другие столбцы, поэтому, если у меня нет нуля в одной из строк столбца, я получу все, кроме нуля.

Спасибо за помощь!


person Dmytro Leonenko    schedule 24.11.2009    source источник
comment
Вы на самом деле хотите подведения итогов или нет? Каким бы вы хотели получить результат, если бы одно из этих нулевых значений на самом деле было 2?   -  person Jon Skeet    schedule 24.11.2009
comment
вам нужно предоставить лучшие образцы данных, чтобы показать, как вы хотите сгруппировать материал и т. д.   -  person Ruben Bartelink    schedule 24.11.2009
comment
Как я уже упоминал в последней фразе, для всего, кроме null, мне нужно какое-то логическое значение true или false. В моем случае null будет ложным, а все остальное будет истинным.   -  person Dmytro Leonenko    schedule 25.11.2009


Ответы (1)


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

РЕДАКТИРОВАТЬ: В ответ на ваше разъяснение...

Я думаю, вы сможете взять его отсюда тогда. Если все, что вы хотите сделать, это выяснить, есть ли столбец в группе, то вам подойдет оператор Any, как в ответе Бруно. Aggregate необходим только в том случае, если вы пытаетесь фактически посетить все значения, чтобы сделать что-то более сложное, например, их суммирование (хотя, как намекнул Джон, Sum обрабатывает этот конкретный случай).

Короче говоря, вам нужна группировка, как в ответе, а затем внутри группы вы либо используете Aggregate для объединения строк за строками, либо несколько Any для результатов GroupBy в зависимости от того, что более ясно в вашем контексте (или более эффективно, если у вас большой набор данных внутри каждой группы)

person Ruben Bartelink    schedule 24.11.2009
comment
Конечно, вы имели в виду Console.WriteLine( {0} {1}{2}{3}{4}, result.N, result.A, result.B, result.C, result.D ); - person Dmytro Leonenko; 25.11.2009
comment
@melco-man: Да, спасибо - изменил его (на самом деле у меня был правильный код в другом месте, но я редактировал изменения в сообщении параллельно, и редактор определенно не помогает делать это в длинных сообщениях!) - person Ruben Bartelink; 25.11.2009