Вопрос

Я пишу свой собственный справочник по LINQ, но у меня возникают проблемы с некоторыми из более сложных реализаций операторов.

Существует реализация соединения, которая использует IEqualityComparer. Я просто схожу с ума.

Я пытаюсь сначала понять это, прежде чем писать (очевидно)

Представьте себе эти два списка:

List<string> initials = new List<string> {"A", "B", "C", "D", "E"};

List<string> words = new List<string> {"Ant", "Crawl", "Pig", "Boat", "Elephant", "Arc"};

Здесь нет ничего странного.Я хочу объединить оба списка по начальному значению, например:

Начальное значение=Слово=Муравей
Начальное значение=Слово=Дуга
Начальное значение=B Слово=Лодка
...

Мне нужен компаратор, я написал это:

public class InitialComparator : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        return x.StartsWith(y);
    }

    public int GetHashCode(string obj)
    {
        return obj[0].GetHashCode();
    }
}

Само соединение:

var blah = initials.Join(words,
                                  initial => initial,
                                  word => word,
                                  (initial, word) =>
                                  new {Initial = initial, Word = word},
                                  new InitialComparator());

Я впервые использую HashCodes, после хорошего сеанса отладки я вижу, что каждое слово идет в компаратор и смотрит на его HashCode, если другое слово имеет тот же HashCode, которое оно называет равным.

Поскольку я хочу сравнить только начальную букву, я подумал, что мне нужна только первая буква Хэш (я ошибаюсь?)

Дело в том, что это работает неправильно.В нем говорится, что «Ant» и «Arc» равны. Хорошо, он сравнивает каждое слово в одном списке или нет. Но он добавляет только последнее найденное слово, в данном случае Arc, игнорируя Ant и Ant, равно «A». " слишком...

Если я поставлю «Ant» и «Ant», будут добавлены оба.

Короче говоря, как это сделать?Я знаю, что делаю что-то не так.

Спасибо.

Это было полезно?

Решение

Как упомянуто хрустяние, попробуйте x [0] == y [0] вместо x.startswith (y);Это сработало для меня.

Другие советы

На самом деле вам не нужен собственный компаратор равенства, просто присоединитесь к отдельному письму следующим образом:

var mine = from i in initials
     join w in words on i[0] equals w[0]
     select new {
          Initial = i,
          Words = w
     };

Я не уверен, почему вы видите такое поведение, но я думаю, что использование «SelectMany» было бы более простым подходом и (что более важно) имело бы желаемое поведение:

var blah =
    from word in words
    from initial in initials
    where (word.StartsWith(initial))
    select new { Initial = initial, Word = word };

Я предпочитаю использовать синтаксис понимания, где это возможно.«SelectMany» вызывается, когда в запросе на понимание имеется несколько предложений «from».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top