#c# #linq
#c# #linq
Вопрос:
Допустим, у меня есть
{ { "a", "b", "c" }, { "d", "b", "c" }, { "z", "a", "c" } }
Я могу перебирать внешний список и выполнять пересечение в каждом внутреннем списке и получать:
{ "a", "b", "c", "d", "z" }
Тем не менее, мне интересно, есть ли что-то встроенное.NET для этого. Я чувствую, что должен быть способ сделать что-то вроде:
listOfLists.Intersect();
Обычно вы помещаете туда другой список для пересечения двух списков, но, похоже, должен быть способ сделать это в LINQ.
В итоге я перегружал его для своих собственных целей, но мне интересно, не нужно ли мне было.
internal static string Intersect(this IEnumerable<string> inputs)
{
var temp = inputs.FirstOrDefault().ToCharArray();
foreach (var item in inputs.Skip(1))
{
temp = temp.Intersect(item).ToArray();
}
return new string(temp);
}
Комментарии:
1. Ваш пример неверен — вы должны получать только
c
в том случае, если вы выполняете пересечение. Вы имели в виду объединение вместо этого? Что вы пытаетесь найти здесь, общие буквы, уникальные буквы? Обратите внимание, что это будет надежно работать только с текстом ASCII.
Ответ №1:
Вы можете использовать оператор Aggregate
LINQ.
internal static string Intersect(this IEnumerable<string> inputs) =>
string.Join("", inputs.Select(x => x.AsEnumerable()).Aggregate((x, y) => x.Union(y)));
Обратите внимание, что ожидаемый результат, который вы показали, — это a Union
из всех букв в трех строках, а не an Intersect
. Но если вы на самом деле имели в виду пересечение, просто используйте x.Intersect(y)
.
Комментарии:
1. Даст ли это лучшую производительность, чем. SelectMany(l => l, (список, элемент) => элемент). Distinct() ?
2. Да, когда я изначально писал вопрос, я спрашивал о пересечении объединения except и concat . Я очистил его только до одного в целях ясности, но не оставил правильный пример. Спасибо.