1

我正在尝试从 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:\苹果\香蕉

我想从 A 和 B 获取目录信息,并从 A 中删除 C:\Apples\Oranges,因为它存在 B。

有没有办法在 LINQ 中做到这一点,或者根本没有办法做到这一点?

4

3 回答 3

2

这可以很简单地完成。List创建第二个目录中所有路径的集合(比 a 或数组更有效地搜索)。然后,您可以轻松地编写一个查询,为您提供目录路径在该集合中的所有项目(或者不在该集合中,如果您想要的话)。请注意,将比较器传递给集合以确保它进行不区分大小写的比较。

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));
于 2013-06-19T17:08:18.120 回答
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));
    }
}
于 2013-06-19T16:46:52.720 回答
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();
于 2013-06-19T17:01:33.987 回答