Нечто подобное должно работать. Является ли это лучшим методом, я не уверен. Это не очень эффективно, потому что для каждого элемента вы повторяете список снова, чтобы получить счетчик.
List<PicInfo> pi = new List<PicInfo>();
IEnumerable<PicInfo> filt = pi.Where(x=>pi.Count(z=>z.FileName==x.FileName)>1);
Надеюсь, код не слишком сложен, чтобы его можно было объяснить. Я всегда думаю, что в любом случае лучше решить это самостоятельно, но если что-то сбивает с толку, просто спросите, и я объясню.
Если вы хотите, чтобы второй фильтр выполнял фильтрацию для того же имени файла и того же хэша, являющегося дубликатом, то вам просто нужно расширить лямбду-счетчик в Count для проверки на хэш.
Очевидно, что если вы просто хотите, чтобы имена файлов были в конце, тогда достаточно просто сделать Select
, чтобы получить просто перечисляемый список этих имен файлов, возможно, с Distinct
, если вы хотите, чтобы они появлялись только один раз.
NB. Код написан от руки, так что простите за опечатки. Может не скомпилироваться впервые и т. Д .; -)
Изменить, чтобы объяснить код - спойлеры! ; -)
На английском языке мы хотим сделать следующее:
для каждого элемента в списке мы хотим выбрать его, если и только если в списке более одного элемента с одинаковым именем файла.
Разбивая это, перебираем список и выбираем вещи, основываясь на критериях, которые мы используем метод Where. Условием нашего метода where является
в списке более одного элемента с одинаковым именем
для этого нам явно нужно посчитать список, поэтому мы используем pi.Count. Однако у нас есть условие, что мы рассчитываем, только если имя файла совпадает, поэтому мы передаем выражение, чтобы сказать ему только считать эти вещи.
Выражение будет работать с каждым элементом списка и возвращать true, если мы хотим считать его, и false, если мы не хотим.
Имя файла, которое нас интересует, находится на x, элементе, который мы фильтруем. Поэтому мы хотим посчитать, сколько элементов имеют имя файла, такое же, как у x.FileName. Таким образом, наше выражение z=>z.FileName==x.FileName
. Таким образом, z - это наша переменная в этом выражении, а x.FileName в этом контексте не меняется, пока мы перебираем z.
Затем мы, конечно, помещаем наши критерии в> 1, чтобы получить желаемое логическое значение.
Если при рассмотрении имени файла и значения хеш-значения вам нужны дубликаты, вы должны расширить часть в Count до z=>z.FileName==x.FileName && z.hashValue==x.hashValue
.
Таким образом, ваш окончательный код для получения различий по обоим значениям будет:
Список пи = новый список ();
Список фильтра = pi.Where (x => pi.Count (z => z.FileName == x.FileName && z.hashValue == x.hashValue)> 1) .ToList ();
Если вы хотите, чтобы те, которые были дубликатами, рассматривали имя файла и hashvalue, то вы бы расширили часть в Count для сравнения hashValue. Поскольку это массив, вы можете использовать метод SequenceEqual , чтобы сравнить их значение по значению.
Таким образом, ваш окончательный код для получения различных значений будет:
List<PicInfo> pi = new List<PicInfo>();
List<PicInfo> filt = pi.Where(x=>pi.Count(z=>z.FileName==x.FileName && z.hashValue.SequenceEqual(x.hashValue))>1).ToList();
Обратите внимание, что я не создал список посредников, а просто пошел прямо из исходного списка. Вы можете перейти из промежуточного списка, но код будет почти таким же, если исходить из оригинала и из отфильтрованного списка.