У меня есть 4 класса, каждый из которых наследуется от одного и того же базового класса. Все они имеют свойство Id & Path. Когда мои данные загружаются из xml, я строю 4 списка на основе этих классов.
У меня есть следующий код, который позволяет мне сравнить 2 списка:
var list1 = settings.EmailFolders.Select(m => m.Path).ToList().
Intersect(settings.LogPaths.Select(m=>m.Path).ToList()).ToList();
но я бы хотел
Я хочу сравнить 1-й список с другими 3 и найти, если существует дублированный путь.
Если ни один не найден, я хочу применить ту же логику, сравнивая второй список и сравнивая ее с другой.
Если ни один не найден, я хочу применить ту же логику, сравнивая третий список, и сравнить ее с последней.
Обратите внимание, что я не хочу, чтобы точки 1, 2 и 3 выполнялись в одном процессе, так как я хотел бы сообщить о соответствующей ошибке, если будут найдены дубликаты.
Если я повторно использую вышеуказанное и добавлю дополнительный Intersect
с дополнительным списком,
var list1 = settings.EmailFolders.Select(m => m.Path).ToList().
Intersect(settings.LogPaths.Select(m=>m.Path).ToList()).
Intersect(settings.SuccessPaths.Select(m=>m.Path).ToList()).
Intersect(settings.FailurePaths.Select(m=>m.Path).ToList()).List();
Вышеизложенное хотелось бы применить оператор a and
operator между каждым, а не оператором or
оператором, который не является тем, что я хочу. Мне нужно знать, если какой-либо из путей, используемых в FailurePaths или LogPaths или SuccessPaths, уже используется в моем почтовом ящике EmailFolder.Path
ОБНОВИТЬ:
Я обновил свой вопрос с ответом на основе предложения @Devuxer, который является правильным ответом, но вместо того, чтобы работать со строковым массивом, я основываю его на списке классов, все из которых содержат свойство Path
.
List<EmailFolder> emailFolders = LoadEmailFolders();
List<LogPath> logPaths = LoadLogPaths();
List<SuccessPath> successPaths = LoadSuccessPaths();
List<FailurePath> failurePaths = LoadFailurePaths();
var pathCollisions = EmailFolders.Select(a=>a.Path)
.Intersect(LogPaths.Select(b=>b.Path))
.Select(x => new { Type = "LogPath", Path = x })
.Concat(EmailFolders.Select(c=>c.Path)
.Intersect(SuccessPaths.Select(d=>d.Path))
.Select(x => new { Type = "SuccessPath", Path = x }))
.Concat(EmailFolders.Select(e=>e.Path)
.Intersect(FailurePaths.Select(f=>f.Path))
.Select(x => new { Type = "FailurePath", Path = x })).ToList();
Обратите внимание, что в приведенном выше примере, для простоты, я только что объявил свой список с функцией для каждого, кто загружает соответствующие данные, но в моем случае все данные десериализуются и загружаются сразу.
Возможно, я немного недооцениваю ваши требования, но похоже, что вы хотите что-то вроде этого:
var emailFolders = new[] { "a", "b", "c" };
var logPaths = new[] { "c", "d", "e" };
var successPaths = new[] { "f", "g", "h" };
var failurePaths = new[] { "a", "c", "h" };
var pathCollisions = emailFolders
.Intersect(logPaths)
.Select(x => new { Type = "Email-Log", Path = x })
.Concat(emailFolders
.Intersect(successPaths)
.Select(x => new { Type = "Email-Success", Path = x }))
.Concat(emailFolders
.Intersect(failurePaths)
.Select(x => new { Type = "Email-Failure", Path = x }));
Это приводит к:
Type | Path
--------------------
Email-Log | c
Email-Failure | a
Email-Failure | c
--------------------
Если это то, что вы искали, Intersect
определенно был правильным способом найти дубликаты. Я просто добавил некоторые предложения Concat
и предоставил Type
чтобы вы могли видеть, какой тип столкновения пути произошел.
редактировать
Ну, пули в вашем вопросе, похоже, просят что-то отличное от последнего предложения вашего вопроса.
Если вы действительно хотите все сравнения, один из способов сделать это - добавить дополнительные предложения Concat
:
var pathCollisions = emailFolders
.Intersect(logPaths)
.Select(x => new { Type = "Email-Log", Path = x })
.Concat(emailFolders
.Intersect(successPaths)
.Select(x => new { Type = "Email-Success", Path = x }))
.Concat(emailFolders
.Intersect(failurePaths)
.Select(x => new { Type = "Email-Failure", Path = x }))
.Concat(logPaths
.Intersect(successPaths)
.Select(x => new { Type = "Log-Success", Path = x }))
.Concat(logPaths
.Intersect(failurePaths)
.Select(x => new { Type = "Log-Failure", Path = x }))
.Concat(successPaths
.Intersect(failurePaths)
.Select(x => new { Type = "Success-Failure", Path = x }));
Тем не менее, это не "короткое замыкание", как вы предполагали (так что он найдет все конфликты пути, а не остановится после первого типа), но он должен по крайней мере предоставить вам данные, необходимые для создания отчета.
Вы можете использовать Содержит, используя свойство для сравнения
var result = list1.Where(x => list2.Contains(x.Path));
Он предоставит все элементы из списка1, которые также находятся в списке2
Если вы хотите только подсчет, используйте.Count() в конце
То же правило применяется для сравнения других 3 списков
new { Type = "Email-Log", Path = x.Path }
для каждогоnew
оператора.