Как реализовать пользовательскую сортировку с помощью IComparer‹T› в C#

У меня есть список имен, как показано ниже, я хочу реализовать пользовательский порядок, реализовав IComparer<T>. Эта пользовательская сортировка должна проверять имена двух элементов, и если они совпадают, она должна объединять их. Так, например, окончательный результат будет

John       Locke
John       Doe
Elizabeth  Davis
Elizabeth  Hurley
Ashley     Williams

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

class Program
{
    static void Main(string[] args)
    {
        List<Name> names = new List<Name>
        {
            new Name {FirstName = "John", LastName = "Locke"},
            new Name {FirstName = "Elizabeth", LastName = "Davis"},
            new Name {FirstName = "John", LastName = "Doe"},
            new Name {FirstName = "Ashley", LastName = "Williams"},
            new Name {FirstName = "Elizabeth", LastName = "Hurley"}
        };

        foreach (Name name in names)
        {
            Console.WriteLine($"{name.FirstName, -10} {name.LastName, -10}");
        }

        Console.WriteLine("\n\n");

        List<Name> sorted = names.OrderBy(o => o, new NameComparer()).ToList();

        foreach (Name name in sorted)
        {
            Console.WriteLine($"{name.FirstName,-10} {name.LastName,-10}");
        }

        Console.ReadKey();
    }
}

public sealed class Name
{
    public string FirstName { get; set; }

    public string LastName { get; set; }
}

public sealed class NameComparer : IComparer<Name>
{
    public int Compare(Name x, Name y)
    {
    }
}

person Vahid    schedule 27.05.2020    source источник
comment
И что у вас за проблема с этим кодом?   -  person Pavel Anikhouski    schedule 27.05.2020
comment
@PavelAnikhouski Я не знаю, как это сделать внутри Compare().   -  person Vahid    schedule 27.05.2020
comment
Что не так с простым names.OrderBy(x => x.FirstName).ThenBy(x => x.LastName).ToList();?   -  person George Kerwood    schedule 27.05.2020
comment
@GeorgeKerwood Я не хочу касаться упорядочения списка по имени, я просто хочу собрать вместе те, у кого одинаковое имя, но другая фамилия.   -  person Vahid    schedule 27.05.2020
comment
@ Вахид, извини, я явно не понял, что ты имеешь в виду под объединением. Пожалуйста, уточните.   -  person George Kerwood    schedule 27.05.2020
comment
@GeorgeKerwood Первым элементом является Джон Лок, затем мы смотрим в список и видим, что Джон Доу также начинается с Джона, поэтому мы приводим его после Джона Локка, следующим элементом теперь является Элизабет Дэвис, мы смотрим и приводим Элизабет Херли рядом с это и так далее.   -  person Vahid    schedule 27.05.2020
comment
@Vahid Вот что такое сортировка ... изменение порядка. Снова взглянув на желаемый результат, вы не хотите создавать список, отсортированный в алфавитном порядке по имени, а только группировать имена в некотором естественном порядке? Могу я спросить, почему?   -  person George Kerwood    schedule 27.05.2020
comment
@GeorgeKerwood Спасибо, Джордж, я не воспринимаю их всерьез :) Я действительно знал, что мне может понадобиться собственный алгоритм для их извлечения, но, поскольку я раньше не использовал IComparer‹T›, я подумал, что попробую, спросив, может быть. Я что-то упустил, как я думал.   -  person Vahid    schedule 27.05.2020
comment
@Vahid, открой вопрос еще раз, я сделал это с IComparer<T> :)   -  person George Kerwood    schedule 27.05.2020
comment
@GeorgeKerwood Я проголосовал за открытие.   -  person Vahid    schedule 27.05.2020
comment
@Vahid, ах, неважно, вот: return x.FirstName == y.FirstName ? 0 : -1; Это все, что тебе нужно в Compare(Name x, Name y)   -  person George Kerwood    schedule 27.05.2020
comment
Он может только перемещать элементы вверх, но будет делать это до тех пор, пока они не сгруппируются. Не идеально для желаемого результата, но будет минимальным сдвигом в группу FirstName.   -  person George Kerwood    schedule 27.05.2020
comment
@GeorgeKerwood Спасибо, Джордж, я очень ценю ваши усилия.   -  person Vahid    schedule 27.05.2020
comment
Давайте продолжим обсуждение в чате.   -  person George Kerwood    schedule 27.05.2020


Ответы (2)



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

public sealed class NameComparer : IComparer<Name>
{
    public int Compare(Name x, Name y) => x.FirstName.CompareTo(y.FirstName);
}
person Blindy    schedule 27.05.2020
comment
Привет, Блинди, я не хочу нарушать общий порядок списка, просто приблизите тех, у кого одинаковые имена. - person Vahid; 27.05.2020
comment
@Vahid Это сближение / сближение всех смутило, мой друг. Тем более, что заголовок вашего вопроса касается сортировки. По определению сортировка — это изменение порядка. - person George Kerwood; 27.05.2020
comment
@GeorgeKerwood Я согласен, я не смог найти для этого правильную формулировку. - person Vahid; 27.05.2020
comment
@GeorgeKerwood Я имею в виду, что сначала в списке есть порядок, я хочу упорядочить его таким образом, чтобы элементы с похожими именами были сгруппированы вместе. - person Vahid; 27.05.2020
comment
Я хочу упорядочить его таким образом, чтобы элементы с похожими именами были сгруппированы вместе. это именно то, что дали вам оба ответа до сих пор, и то, что вы, скорее всего, получите, пока кто-то просто не закроет ваш вопрос за то, что он искажен, независимо от ваших отрицательных голосов. - person Blindy; 27.05.2020
comment
Нет, ваше решение не то, что я имею в виду! ,) - person Vahid; 27.05.2020
comment
Но он делает то, что вы сказали. - person Blindy; 27.05.2020