Сортировка Linq по элементу в списке - PullRequest
0 голосов
/ 12 июля 2020

У меня есть список людей, и мне нужно отсортировать этот список по их роли и создать строку, разделенную запятыми, с именами людей.

Допустим, класс People:

public class Person
{
     public string FirstName { get; set; }
     public string LastName { get; set; }
     public string Role { get; set; }
}

У нас пять разных ролей: архитекторы, разработчики, тестировщики, BA и дизайнер.

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

Я пробовал использовать var groups = people.GroupBy(i => i.Role);. Но я не знаю, как разбираться в этом. Я был бы признателен за помощь

Обновление 1

Спасибо за помощь. Прежде всего мои искренние извинения. Я немного упростил свой вопрос, но полагаю, что способ его изложения изменил постановку задачи. Есть 2 важные вещи.

  1. Роль - это не перечисление, это строка.
  2. В списке может быть больше ролей, его текстовое поле произвольной формы, но мы только беспокоит это инженеров и архитекторов. Остальные могут быть в любом порядке

Ответы [ 4 ]

0 голосов
/ 12 июля 2020

Вы можете использовать свободный синтаксис API LINQ вот так:

var people = new List<Person>()
{
    new Person() { FirstName = "A", Role = "Developer" },
    new Person() { FirstName = "B", Role = "Designer" },
    new Person() { FirstName = "C", Role = "Architect" },
    new Person() { FirstName = "D", Role = "Developer" },
};

// sort this list by their role and create a comma separated string with the first name of the people
var result = people
    .GroupBy(p => p.Role)
    .Select(g => new { Role = g.Key, Names = string.Join(",", g.Select(c => c.FirstName)) })
    .OrderBy(c => c.Role)
    .ToList();

введите описание изображения здесь

0 голосов
/ 12 июля 2020

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

var roleOrders = new Dictionary<string, int>()
{
    { "Developer", 2 },
    { "Architect", 1 },
    // You can add more roles here for priority ordering
};

var roleNames = people.GroupBy(p => p.Role, p => p.FirstName)
    .OrderBy(r => roleOrders.TryGetValue(r.Key, out var order) ? order : int.MaxValue)
    .ToDictionary(
        g => g.Key,
        g => string.Join(", ", g));
0 голосов
/ 12 июля 2020

Мне кажется, что это простой способ сделать это:

var people = new List<Person>()
{
    new Person() { FirstName = "A", Role = "Developer" },
    new Person() { FirstName = "B", Role = "Designer" },
    new Person() { FirstName = "C", Role = "Architect" },
    new Person() { FirstName = "D", Role = "Developer" },
};

int RolePriority(string role) =>
    role == "Architect" ? 0 : (role == "Developer" ? 1 : 2);

var ouput =
    from p in people
    group p.FirstName by p.Role into g
    orderby RolePriority(g.Key)
    select new
    {
        role = g.Key,
        names = String.Join(", ", g),
    };

Это дает мне:

вывод

Вы можете установить порядок ролей, изменив локальную функцию RolePriority.

0 голосов
/ 12 июля 2020

Я вижу два варианта:

  1. Сделать роль перечислением и упорядочить роли для сортировки:
enum Role {
    Architect = 1,
    Engineer = 2,
    // the rest of them
}

var groups = people.OrderBy(i => i.Role); // I think this will work
var groups = people.OrderBy(i => (int)i.Role); // an alternative 
(менее красиво) Создайте Dictionary<string,int>, который будет назначать целочисленное значение ролям. Затем вы можете заказать по этим значениям:
var groups = people.OrderBy(i => roles[i.Role]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...