2016-03-09 2 views
1

У меня есть следующий код, который стыковой некрасиво, и я хотел бы переписать его с некоторым хорошим LINQ, но я не могу понять:Как переписать этот код в LINQ?

var folders = new List<string>(); 
string folderResult = ""; 

foreach (var parallelMeasurement in ParallelMeasurements) 
{ 
    var folder = parallelMeasurement.Item1.Substring(0, parallelMeasurement.Item1.IndexOf(".")); 

    if (!folders.Contains(folder)) 
    { 
     folders.Add(folder); 
     folderResult += folder + ","; 
    } 
} 

folderResult = folderResult.TrimEnd(','); 

string valueResult = ""; 

foreach (var folder in folders) 
{ 
    var views = ParallelMeasurements.Where(x => x.Item1.Substring(0, x.Item1.IndexOf(".")) == folder); 

    var value = views.Sum(x => x.Item2.TotalSeconds); 
    valueResult += value + ","; 
} 

valueResult = valueResult.TrimEnd(','); 

File.WriteAllText(Paths.ParallelGroupedTrend, $"{folderResult}{Environment.NewLine}{valueResult}"); 

ParallelMeasurements является List<Tuple<string, TimeSpan>> и содержание tuple.Item1 является например:

Actor.ActorUsers 
Actor.ActorInformation 
User.Edit 

Короче говоря, я хочу, чтобы агрегировать измерения на основе первой части строки, содержимое до периода.

+1

'если (folders.Contains (папка)) {folders.Add (папка);' ...? –

+0

@ Томас спасибо, это была прикладом уродливая ошибка там! – Drutten

ответ

4

Это должно делать?

ParallelMeasurements.Add(new Tuple<string, TimeSpan>("Actor.ActorUsers", TimeSpan.FromMilliseconds(150))); 
ParallelMeasurements.Add(new Tuple<string, TimeSpan>("Actor.ActorInformation", TimeSpan.FromMilliseconds(200))); 
ParallelMeasurements.Add(new Tuple<string, TimeSpan>("User.Edit", TimeSpan.FromMilliseconds(150))); 

var folders = 
    ParallelMeasurements 
     .GroupBy(g => g.Item1.Substring(0, g.Item1.IndexOf(".", StringComparison.InvariantCulture))) 
     .Select(s => new { Group = s.Key, Sum = s.Sum(a => a.Item2.Milliseconds) }) 
     .ToList(); 

var folderResult = string.Join(",", folders.Select(f => f.Group)); 
var valueResult = string.Join(",", folders.Select(f => f.Sum)); 

Console.WriteLine("{0}{1}{2}", folderResult, Environment.NewLine, valueResult); 

печать из

Actor,User 
350,150 
+0

Красивая! Почему свойство анонимной папки? ('Folder = s.Item1') – Drutten

+1

Просто вам нужно исходное значение где-то, не нужно, хотя кажется. –

+0

Итак, если мы удалим материал 'Folder = s.Item1', можем ли мы удалить один оператор' Select'? – Drutten

2

Как так:

var folders = new List<string>(); 
foreach (var parallelMeasurement in ParallelMeasurements) 
{ 
    folders.Add(parallelMeasurement.Item1.Substring(0, parallelMeasurement.Item1.IndexOf("."))); 
} 
string folderResult = String.Join(',', folders.Disctint().toList()); 

var values = new List<int>(); 
foreach (var folder in folders) 
{ 
    values.Add(ParallelMeasurements.Where(x => x.Item1.Substring(0, x.Item1.IndexOf(".")) == folder).Sum(x => x.Item2.TotalSeconds)); 
} 
string valueResult = String.Join(',', values); 
+0

Downvoter: помочь объяснить? –

+0

'Disctinct',' toList', добавляя результат 'Sum' в' Список ', вызывающий« disctinct »в списке результатов суммы ... – Rawling

+1

Я не делал нисходящего, но я полагаю, что OP хотел бы для удаления петель 'foreach'. –

1

LINQ-возможности? Да. Менее безобразно? Спорно!

List<string> folders = new List<string>(); 

string folderResult = string.Join(",", ParallelMeasurements 
    .Select(parallelMeasurement => parallelMeasurement.Item1.Substring(0, parallelMeasurement.Item1.IndexOf("."))) 
    .Where(folder => folders.Contains(folder)) 
    .Select(folder => 
    { 
     folders.Add(folder); 
     return folder; 
    })); 

string valueResult = string.Join(",", folders 
    .Select(folder => ParallelMeasurements 
     .Where(parallelMeasurement => parallelMeasurement.Item1.Substring(0, parallelMeasurement.Item1.IndexOf(".")) == folder)) 
     .Select(views => views.Sum(view => view.Item2.TotalSeconds))); 
+1

Дискуссионный? Я люблю его, его красиво! :-) – Drutten

+0

Не понимаю, что выбрать часть возврата, хотя. – Drutten

+1

Добавление '{...}' позволяет писать произвольный код в инструкции select - пока вы возвращаете значение для выбора, которое он не будет жаловаться. Вы должны быть очень осторожны в отложенном исполнении в этом случае - что-то, что я не смог проверить в этом примере. – TVOHM

1
var folders = new List<string>(); 
string folderResult = ""; 

foreach (var folder in ParallelMeasurements.Select(parallelMeasurement => parallelMeasurement. 
         Item1.Substring(0, parallelMeasurement.Item1.IndexOf("."))). 
         Where(folder => !folders.Contains(folder))) 
{ 
    folders.Add(folder); 
    folderResult += folder + ","; 
} 

folderResult = folderResult.TrimEnd(','); 

string valueResult = folders.Select(folder => ParallelMeasurements. 
            Where(x => x.Item1.Substring(0, x.Item1.IndexOf(".")) == 
      folder)).Select(views => views.Sum(x => x.Item2.TotalSeconds)).Aggregate("", (current, value) => current + (value + ",")); 

    valueResult = valueResult.TrimEnd(',');