我正在尝试从DirectoryInfo dInfoA中删除dInfoA,其中包含dInfoB中列出的目录。
DirectoryInfo Dinfo = new DirectoryInfo(@"C:\Apples");
DirectoryInfo[] dInfoA = Dinfo.GetDirectories("*.*", SearchOption.AllDirectories);
DirectoryInfo DinfoB = new DirectoryInfo(@"C:\Apples\Oranges");
DirectoryInfo[] dInfoB = DinfoB.GetDirectories("*.*", SearchOption.AllDirectories);
文件夹结构如下:
C:\苹果
C:\苹果\桔子
C:\苹果\ banannas
我想从A和B获取目录信息,并从A中删除C:\ Apples \ Oranges,因为它存在B.
有没有办法在LINQ中执行此操作,或者完全按照这种方式执行此操作?
答案 0 :(得分:2)
这可以做得很简单。创建第二个目录中所有路径的集合(可以比List
或数组更有效地搜索)。然后,您可以轻松编写查询,以便为您提供目录路径在该集合中的所有项目(或者不在该集合中,如果这是您想要的那样)。请注意,Comparer传递给集合以确保它进行不区分大小写的比较。
var directoryBPaths = new HashSet<string>(dInfoB.Select(dir => dir.FullName),
StringComparer.InvariantCultureIgnoreCase);
var directoriesToRemove = dInfoA.Where(dir =>
directoryBPaths.Contains(dir.FullName));
//If you just want a sequence of the items not
//in the other set, get that directly
var directoriesToKeep = dInfoA.Where(dir =>
!directoryBPaths.Contains(dir.FullName));
答案 1 :(得分:0)
您可以使用MoreLINQ和ExceptBy
:
dInfoB = dInfoB.ExceptBy(dInfoA, n => n.FullName,
StringComparer.InvariantCultureIgnoreCase).ToArray();
如果您无法访问MoreLINQ,您也可以使用这种(稍微)效率较低的方式:
dInfoB = dInfoB.Except(dInfoA,
PropertyEqualityComparer.GetNew<DirectoryInfo, string>
(n => n.FullName, StringComparer.InvariantCultureIgnoreCase)).ToArray();
效率仍然高于Where
+ Any
。
如果我得到了你想要做的事情。额外的比较器是因为DirectoryInfo决定它不想覆盖Equals
。
比较器是这样的:
public class PropertyEqualityComparer<TObject, TProperty>
: IEqualityComparer<TObject>
{
Func<TObject, TProperty> _selector;
IEqualityComparer<TProperty> _internalComparer;
public PropertyEqualityComparer(Func<TObject, TProperty> propertySelector,
IEqualityComparer<TProperty> innerEqualityComparer = null)
{
_selector = propertySelector;
_internalComparer = innerEqualityComparer;
}
public int GetHashCode(TObject obj)
{
return _selector(obj).GetHashCode();
}
public bool Equals(TObject x, TObject y)
{
IEqualityComparer<TProperty> comparer =
_internalComparer ?? EqualityComparer<TProperty>.Default;
return comparer.Equals(_selector(x), _selector(y));
}
}
答案 2 :(得分:0)
GetDirectories
将无法获取基目录,因此B
将为空。
您必须添加根才能实现目标。
检查出来:
DirectoryInfo rootA = new DirectoryInfo(@"C:\Apples");
List<DirectoryInfo> listA = rootA.GetDirectories("*.*", SearchOption.AllDirectories).ToList();
listA.Add(rootA);
DirectoryInfo rootB = new DirectoryInfo(@"C:\Apples\Oranges");
List<DirectoryInfo> listB = rootB.GetDirectories("*.*", SearchOption.AllDirectories).ToList();
listB.Add(rootB);
DirectoryInfo[] aDiffB = listA.Where(x => !listB.Any(y => string.Equals(y.FullName, x.FullName, StringComparison.InvariantCultureIgnoreCase))).ToArray();