假设我有两个列表,分别包含源文件名和目标文件名列表.
Sourcefilenamelist包含1.txt,2.txt,3.txt,4.txt文件
而Destinaitonlist有1.txt,2.txt.
我想写一个linq查询来找出SourceList中哪些文件在DestinationFile列表中不存在.
例如,输出将是3.txt和4.txt.我是通过foreach声明完成的.但现在我想通过使用LINQ(C#)来做同样的事情.
编辑:
我的代码是
List<FileList> sourceFileNames = new List<FileList>();
sourceFileNames.Add(new FileList { FileNames = "1.txt" });
sourceFileNames.Add(new FileList { FileNames = "2.txt" });
sourceFileNames.Add(new FileList { FileNames = "3.txt" });
sourceFileNames.Add(new FileList { FileNames = "4.txt" });
List<FileList> destinationFileNames = new List<FileList>();
destinationFileNames.Add(new FileList { FileNames = "1.txt" });
destinationFileNames.Add(new FileList { FileNames = "2.txt" });
IEnumerable<FileList> except = sourceFileNames.Except(destinationFileNames);
Run Code Online (Sandbox Code Playgroud)
并且Filelist是一个简单的类,只有一个属性fileNames类型为string.
class FileList
{
public string FileNames { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 14
这Except是为了:
var files = sourceFilenameList.Except(destinationList);
Run Code Online (Sandbox Code Playgroud)
请注意,这是一个设置操作,因此如果源列表有重复的条目,您将只看到唯一的结果:new[] {a, a, b, b, c}.Except(new[] {b, c})只是{a},不是{a, a}.
像许多LINQ运算符一样,这会返回一个IEnumerable<T>- 如果你想要它作为一个List只是调用ToList:
var files = sourceFilenameList.Except(destinationList).ToList();
Run Code Online (Sandbox Code Playgroud)
编辑:好的,现在你已经展示了什么FileList,问题只是你没有实现相等比较.您可以通过覆盖Equals和GetHashCode(可能IEquatable<FileList>)或通过实现来实现此目的IEqualityComparer<T>.但是,你仍然遇到了一个问题:它FileNames是一个可变类型,并且在散列和相等方面通常不能很好地工作.最初两个实例可能相等,然后其中一个可以更改.我建议将其重新实现为不可变类型.像这样的东西:
public sealed class FileList : IEquatable<FileList>
{
private readonly string fileNames;
public string FileNames { get { return fileNames; } }
public FileList(string fileNames)
{
// If you want to allow a null FileNames, you'll need to change
// the code in a few places
if (fileNames == null)
{
throw new ArgumentNullException("fileNames");
}
this.fileNames = fileNames;
}
public override int GetHashCode()
{
return fileNames.GetHashCode();
}
public override bool Equals(object other)
{
return Equals(other as FileList);
}
public bool Equals(FileList other)
{
return other != null && other.FileNames == FileNames;
}
}
Run Code Online (Sandbox Code Playgroud)
您的示例代码可能会变为:
List<FileList> sourceFileNames = new List<FileList>
{
new FileList("1.txt"),
new FileList("2.txt"),
new FileList("3.txt"),
new FileList("4.txt")
};
List<FileList> destinationFileNames = new List<FileList>
{
new FileList("1.txt"),
new FileList("2.txt")
};
IEnumerable<FileList> except = sourceFileNames.Except(destinationFileNames);
Run Code Online (Sandbox Code Playgroud)
不太难做到.在FileList类中,创建一个继承自IEqualityComparer <>的子类
public class FileListComparer : IEqualityComparer<FileList>
{
public bool Equals(FileList x, FileList y)
{
if (x == null || y == null)
{
return false;
}
return x.FileNames.Equals(y.FileNames, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(FileList obj) { return base.GetHashCode(); }
}
Run Code Online (Sandbox Code Playgroud)
然后当您调用Except时,请使用Comparer
IEnumerable<FileList> except = sourceFileNames.Except(destinationFileNames, new FileList.FileListComparer() );
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1018 次 |
| 最近记录: |