У меня есть два IEnumerable, один с обязательной базой ключей, другой с множеством ключей со всеми видами написания (одинаковые значения, но содержащие escape-последовательности, разные заглавные буквы и т. д.). Я хочу создать сопоставление между каждым ключом первого списка и всеми теми, которые соответствуют строкам во втором списке (предикат bool IsPossibleMatch(string a, string b)
)
Так что в основном я хочу IGrouping<string, IEnumerable<string>>
, потому что это именно та структура, которую я ищу.
Я пробовал разные версии keys.GroupBy((x,y) => IsPossibleMatch(x, y))
, но ни одна из них не работала.
Теперь мне интересно: возможно ли это вообще с группой? Или мне нужно вручную сделать это каким-то другим способом?
Верхний/нижний, да, но есть и кое-что еще, например, мне также нужно следить за некоторыми экранированными последовательностями. Первый список может, например, содержать «AlphaBeta», а группировка будет содержать такие значения, как {«AlphaBeta», «alphaBeta», alpha<beta"} и т. д. Однако я уже написал предикат для этого: bool IsPossibleMatch(string a, string b)
Пожалуйста, отредактируйте вопрос, чтобы включить эту информацию в вопрос
Вот пример кода:
var left = new string[] {
"key1",
"key2",
"key3",
"key4",
"key5"
};
var right = new string[]
{
"key1",
"Key1",
"KEy1",
"KEY1",
"KeY1",
"kEY1",
"kEy1",
"key2",
"Key2",
"KEy2",
"KEY2",
"KeY2",
"kEY2",
"kEy2"
};
var output = left.GroupJoin(
right,
leftStr => leftStr.ToLower(),
rightStr => rightStr.ToLower(),
(x,y)=>(x,y)
);
foreach (var leftKey in output)
Console.WriteLine(leftKey.x + "->" + string.Join(",", leftKey.y));
Производит следующий вывод:
key1->key1,Key1,KEy1,KEY1,KeY1,kEY1,kEy1
key2->key2,Key2,KEy2,KEY2,KeY2,kEY2,kEy2
key3->
key4->
key5->
Присоединяйтесь к группе! Даже не знал, что такое существует! Я решил, что мне нужно присоединиться, но я не хотел смешивать списки, сначала присоединяясь, а затем группируясь. Спасибо!
Тем не менее, дополнительный вопрос: я пытаюсь изменить существующий IsPossibleMatch для реализации IEqualityComparer<string>, чтобы получить правильный результат. Это легко для метода Equals(a, b), но мне интересно, нужен ли он мне вообще. Правильно ли я предполагаю, что GroupJoin СНАЧАЛА вызывает GetHashCode(), чтобы проверить, возможно ли вообще использование Equals, а ЗАТЕМ устраняет ложные срабатывания (коллизии), вызывая Equals()? Потому что для моего использования я мог бы просто заставить GetHashCode() возвращать одно и то же целое каждый раз, чтобы мне не приходилось дважды выполнять одни и те же ресурсоемкие вычисления, как в Equals, так и в GetHashCode. @Leighton Richtie
Глядя на справочный источник, видно, что он использует компаратор равенства по умолчанию EqualityComparer<TKey>.Default
. Возможно, вы можете попробовать создать свой собственный класс с переопределением его метода Equals
, тогда вы сможете заставить его делать что угодно внутри. Тем не менее, это довольно микро-оптимизация, и я не ожидаю, что вы получите значительное улучшение производительности. Скорее всего, узкое место где-то в другом месте, а не здесь.
Пожалуйста, покажите некоторые примеры данных, а также то, что вы пробовали? Что значит "все виды правописания"? Различия только в верхнем/нижнем регистре?