C# | Linq упрощение

Имею:

List<Structure> list = new() {new(param1:"value1.1", param2:"value1.2"),new(param1:"value2.1", param2: "value2.2"),...}

Написал две функции для выбора:

string[] getParam2()
    {
        List<string> result = list.Select(p => p.param2).Distinct().ToList();
        result.Sort();

        result.Add("value");
        return result.ToArray();
    }

string[] getParam1(string param2)
    {
        List<string> result = list.Where(p => p.param2 == param2).Select(p => p.param1).ToList();                
        result.Sort();

        result.Add("value");
        return result.ToArray();
    }

Следующий вопрос, возможно ли эти функции еще упростить? Хотелось бы привести к чему-то такому:

string[] getParam2()
    {
        return list.Select(p => p.param2).Distinct().ToList().Sort().Add("value").ToArray();  
    }

string[] getParam1(string param2)
    {
        return  list.Where(p => p.param2 == param2).Select(p => p.param1).ToList().Sort().Add("value").ToArray();  
    }

Из-за неявных преобразований, компилятор не способен этого сделать. Поэтому прошу знатоков подсказать, как можно улучшить написанные мной функции.


Ответы (1 шт):

Автор решения: Pavel Mayorov

Да, можно. Достаточно лишь воспользоваться OrderBy и Concat:

string[] getParam2() =>
    list.Select(x => x.param2).OrderBy(x => x).Distinct().Concat("value").ToArray();

И со вторым методом аналогично.

Однако, зачем вам каждый раз обходить весь список целиком? Это же долго! Не лучше ли использовать стандартный подход со словарём списков?

Dictionary<string, List<string>> listByParam2;

// listByParam2 = list.GroupBy(p => p.param2, p => p.param1).ToDictionary(g => g.Key, g => g.ToList());

string[] getParam2() =>
    listByParam2.Keys.OrderBy(x => x).Concat("value").ToArray();

string[] getParam2(string param2) =>
    (listByParam2.TryGetValue(param2, out var x) ? x : Enumerable.Empty<string>())
        .OrderBy(x => x).Concat("value").ToArray();

А если ваш список неизменяемый - то можно воспользоваться методом ToLookup:

ILookup<string, string> listByParam2;

// listByParam2 = list.ToLookup(p => p.param2, p => p.param1);

string[] getParam2() =>
    listByParam2.Select(x => x.Key).OrderBy(x => x).Concat("value").ToArray();
string[] getParam2(string param2) =>
    listByParam2[p].OrderBy(x => x).Concat("value").ToArray();
→ Ссылка