Как вернуть значения CSV из списка <T> - PullRequest
0 голосов
/ 10 октября 2011

У меня есть List<item>, содержащий следующие элементы коллекции имен, лет и значений

Names   years  Values
=====   =====  =====
Smith   2010   777
Smith   2011   999
Jones   2007   01
Jones   2008   03
Jones   2009   05
Jones   2010   06
Jones   2011   09

Я хочу написать запрос LINQ, который возвращает мне строку значений CSV с последующим «именем»«значениями» для каждого года, начинающегося с самого раннего года (в данном случае его 2007) и если данные «лет» отсутствуют / отсутствуют (в этом случае Смит не имеет значений для 2007,2008,2009), то подставьтерезультат с 0

следующим образом:

Results:
Smith,0,0,0,777,999
Jones,01,03,05,06,09

Ответы [ 2 ]

1 голос
/ 10 октября 2011

Вы хотели решение Linq, вот оно:

list
    .Select(i=>i.Name)
    .Distinct()
    .Select(name => 
       name + "," + 
       String.Join(",", (from y in list.Select(i=>i.Year).Distinct().OrderBy(y=>y)
                        join item in list.Where(i=>i.Name == name) 
                        on y equals item.Year into outer
                    from o in outer.DefaultIfEmpty()
                    select ((o == null) ? "0" : o.Value.ToString()) 
                         ).ToArray()));

Вы можете увидеть это в действии здесь:
http://www.coderun.com/ide/?w=9QASFzOJrECO3SJDdUo93A
Просто нажмите «Run»

Разве Линк не могущественен или что ...

1 голос
/ 10 октября 2011

Вы можете сделать это следующим образом:

var minYear = items.Min(i => i.Year);
var maxYear = items.Max(i => i.Year);

var names = items.Select(i => i.Name).Distinct();

using (TextWriter writer = …)
{
    foreach (var name in names)
    {
        writer.Write(name);

        for (int y = minYear; y <= maxYear; y++)
        {
            writer.Write(',');

            var value = items.Where(i => i.Name == name && i.Year == y)
                             .Select(i => i.Value)
                             .SingleOrDefault();

            writer.Write(value);
        }

        writer.WriteLine();
    }
}

Это излишне будет проходить через коллекцию items много раз.Так что, если скорость важна для вас, вам, вероятно, следует использовать один или несколько словарей.

...