#c# #linq #c#-8.0
Вопрос:
У меня есть список объектов со свойствами даты, времени и приоритета.
public class DayResponse
{
public DateTime Date { get; set; }
public int Priority { get; set; }
...
}
Могут быть объекты с одинаковой датой, но с разным приоритетом (1 — наивысший приоритет, 6 — самый низкий), а затем я хочу получить объект с наивысшим (наименьшим значением int) приоритетом. Таким образом, результатом должен быть список с объектами со всеми уникальными датами, а там, где были «конфликты», тот, у которого наивысший приоритет, является тем, который в результате. Есть ли linqquery для выполнения этого? Я знаю, что могу получить разные даты, а затем перебирать их, и если на одну и ту же дату приходится более одной, получите наивысший приоритет, но с linq всегда хорошо 🙂 У меня есть пакет MoreLINQ, так что DistinctBy существует.
Ответ №1:
Вы можете сгруппировать записи по их Date
признаку , а затем выбрать ту , которая используется с наименьшим Priority
использованием MinBy
.
sequence.GroupBy(d => d.Date).Select(g => g.MinBy(d => d.Priority));
MinBy
доступен из коробки с System.Linq
тех пор .NET 6
. Он также может быть взят из MoreLinq
, но обратите внимание, что в MoreLinq
возвращаемом типе есть перечисляемый, содержащий все значения, которые имеют одинаковый минимальный приоритет, поэтому вам нужно использовать SelectMany
:
sequence.GroupBy(d => d.Date).SelectMany(g => g.MinBy(d => d.Priority));
Демо-версия для .NET 6:
using System;
using System.Linq;
var sequence = new DayResponse[] {
new() { Date = new DateTime(2000, 01, 01), Priority = 1},
new() { Date = new DateTime(2001, 01, 01), Priority = 2},
new() { Date = new DateTime(2001, 01, 01), Priority = 5},
};
var distinct = sequence.GroupBy(d => d.Date).Select(g => g.MinBy(d => d.Priority));
foreach (var x in distinct)
{
Console.WriteLine($"DayResponse: Date = {x.Date}, Priority = {x.Priority}");
}
public class DayResponse
{
public DateTime Date { get; set; }
public int Priority { get; set; }
}
Доступно здесь: https://dotnetfiddle.net/SLnkSr
Комментарии:
1. Я не хочу указывать версию c #, поэтому некоторые части предоставленного кода мне приходится переписывать, но поскольку я запускаю это в Core 3.1 c # 8, я не знаю, есть ли какие-то языковые возможности, которые мне не хватает, но для меня distinct — это IEnumerable<IExtremaEnumerable<DayResponse>> и xне удается разрешить дату или приоритет
2. @Hyzac Мой плохой, я забыл, что MoreLINQ имеет другую подпись
MinBy
и возвращает все элементы, которые имеют одинаковое значение, на которое вы хотите минимизировать. Обновил ответ, чтобы отразить это.