c # - использование SelectMany для объединения нескольких списков - PullRequest
0 голосов
/ 12 ноября 2018

На данный момент я использую следующий код, чтобы объединить два List<string> списка и упорядочить их по отметке времени

var list = report[0];  
var list2 = report[1];
var result = list
    .Union(list2)
    .Select(x =>
    {  return new {Log = x, Time = TimeSpan.Parse(x.Split(' ')[0])}; })
    .OrderBy(x => x.Time)
    .ToList(); 

Проблема в том, что мне приходится обрабатывать более двух списков, до n. Я рассмотрел примеры SelectMany, но, похоже, он не поддерживает ту же функциональность, что и Select. Другой способ, которым я планировал сделать это, это использовать цикл foreach, но он не кажется эффективным, особенно если список увеличивается.
Редактировать (добавлены данные выборки и ожидаемый результат):
Пример list1 может выглядеть примерно так:
11:03:01:003 INFO some event has occurred 11:03:31:004 DEBUG another event has occurred 11:04:01:015 INFO third event has occurred
Пример list2 может выглядеть примерно так:
11:03:16:003 INFO fourth event has occurred 11:03:32:025 DEBUG fifth event has occurred 11:03:54:023 INFO sixth event has occurred
И, следовательно, может быть несколько списков, как это. Ожидаемое слияние этих двух списков будет выглядеть следующим образом:
11:03:01:003 INFO some event has occurred 11:03:16:003 INFO fourth event has occurred 11:03:31:004 DEBUG another event has occurred 11:03:32:025 DEBUG fifth event has occurred 11:03:54:023 INFO sixth event has occurred 11:04:01:015 INFO third event has occurred

Ответы [ 4 ]

0 голосов
/ 12 ноября 2018

Не уверен, почему другие ответы имеют дополнительные .Select:

var result = report
       .SelectMany(l => l, (l, x) => new { Log = x, Time = TimeSpan.Parse(x.Split(' ')[0]) })
       .Distinct().OrderBy(x => x.Time).ToList(); 
0 голосов
/ 12 ноября 2018

Для этого есть несколько решений, одним из которых может быть:

List<IEnumerable<string>> allLists = new List<IEnumerable<string>>();
            allLists.Add(report[0]);
            allLists.Add(report[1]);
            allLists.Add(report[2]);

            var result = allLists.SelectMany(l => l.Select(x => new
            {
                Log = x,
                Time = TimeSpan.Parse(x.Split(' ')[0])
            })).OrderBy(x => x.Time)
            .ToList();
0 голосов
/ 12 ноября 2018

Вы можете использовать SelectMany здесь:

// suppose reports is of type List<List<SomeClass>>
reports.SelectMany(x => x)
    .Select(x =>
        {  return new {Log = x, Time = TimeSpan.Parse(x.Split(' ')[0])}; })
    .OrderBy(x => x.Time)
    .ToList(); 

Добавление вызова .Distinct приведет к тому же эффекту, что и Union:

reports.SelectMany(x => x).Distinct()
    .Select(x =>
        {  return new {Log = x, Time = TimeSpan.Parse(x.Split(' ')[0])}; })
    .OrderBy(x => x.Time)
    .ToList(); 

Либо продолжайте использовать Union:

IEnumerable<SomeClass> query = reports[0];
for (int i = 1 ; i < reports.Length ; i++) {
   query = query.Union(reports[i]);
}
0 голосов
/ 12 ноября 2018

Я предполагаю, что report - это IEnumerable из IEnumerable<string>.Поэтому вам нужно что-то вроде этого:

report.SelectMany(l => l.Select(x => new {Log = x, Time = TimeSpan.Parse(x.Split(' ')[0])}))
    .OrderBy(x => x.Time)
    .ToList();

SelectMany объединит все результаты l.Select, затем вы упорядочите их по времени.

РЕДАКТИРОВАТЬ:

Поскольку было указано, что Union удаляет дубликаты, вам нужно добавить Distinct, чтобы получить тот же результат:

report.SelectMany(l => l.Select(x => new {Log = x, Time = TimeSpan.Parse(x.Split(' ')[0])}))
    .Distinct()
    .OrderBy(x => x.Time)
    .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...