比较两个DirectoryInfo并从存在B的A中删除。 LINQ?

时间:2013-06-19 16:44:00

标签: c# linq directoryinfo

我正在尝试从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中执行此操作,或者完全按照这种方式执行此操作?

3 个答案:

答案 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)

您可以使用MoreLINQExceptBy

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();