Реализация собственного IComparer со строкой - PullRequest
17 голосов
/ 23 января 2012

У меня есть коллекция строк в c #, например;

var example = new string[]{"c", "b", "a", "d"};

Затем я сортирую это, но мой метод IComparer не работает, и кажется, что цикл бесконечный.

В основном мне нужно, чтобы "b" был первым, а затем "c", тогда я не забочусь о порядке других.

Возможно ли это с использованием I Comparer<string> и метода Compare(string x, string y)?

Редактировать: Код

    public int Compare(string x, string y)
    {
        var sOrder = new string[] { "b", "c" };
        int index_x = -1;
        int index_y = -1;

        for (int i = 0; i < sOrder.Length;i++)
        {
            if (sOrder[i] == x)
                index_x = i;
            else if (sOrder[i] == y)
                index_y = i;
        }

        if (index_x >= 0 && index_y >= 0)
        {
            if (index_x < index_y)
            {
                return -1;
            }
            else
                return 1;
        }
        return 0;
    }

Ответы [ 2 ]

28 голосов
/ 23 января 2012

Это должно делать то, что вы хотите:

var example = new string[]{"c", "a", "d", "b"};
var comparer = new CustomStringComparer(StringComparer.CurrentCulture);
Array.Sort(example, comparer);

...

class CustomStringComparer : IComparer<string>
{
    private readonly IComparer<string> _baseComparer;
    public CustomStringComparer(IComparer<string> baseComparer)
    {
        _baseComparer = baseComparer;
    }

    public int Compare(string x, string y)
    {
        if (_baseComparer.Compare(x, y) == 0)
            return 0;

        // "b" comes before everything else
        if (_baseComparer.Compare(x, "b") == 0)
            return -1;
        if (_baseComparer.Compare(y, "b") == 0)
            return 1;

        // "c" comes next
        if (_baseComparer.Compare(x, "c") == 0)
            return -1;
        if (_baseComparer.Compare(y, "c") == 0)
            return 1;

        return _baseComparer.Compare(x, y);
    }
}
7 голосов
/ 23 января 2012

Простой способ - заменить строки целыми числами.

class MyComparer : IComparer<string>
{
    public override int Compare(string x, string y)
    {
        int ix = x == "b" ? 0 : x == "c" ? 1 : 2;
        int iy = y == "b" ? 0 : y == "c" ? 1 : 2;
        return ix.CompareTo(iy);
    }
}

var example = new List<string> { "c", "b", "a", "d", "foo", "", "1", "e"};
example.Sort(new MyComparer());
foreach (var s in example)
    Console.WriteLine(s);

Вывод:

b
c

1
e
a
d
foo

Обратите внимание, что это не стабильная сортировка.Если вам нужна стабильная сортировка, потребуется немного больше работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...