如何使用LINQ筛选符合特定患者ID条件的归档文件?
问题:筛选符合条件的归档文件
示例数据
List<string> localPatientsIDs = new List<string> { "1550615", "1688", "1760654", "1940629", "34277", "48083" }; List<string> remotePatientsIDs = new List<string> { "000-007", "002443", "002446", "214", "34277", "48083" }; List<string> archivedFiles = new List<string>{ @"G:\Archive\000-007_20230526175817297.zip", @"G:\Archive\002443_20230526183639562.zip", @"G:\Archive\002446_20230526183334407.zip", @"G:\Archive\14967_20240703150011899.zip", @"G:\Archive\214_20231213150003676.zip", @"G:\Archive\34277_20230526200048891.zip", @"G:\Archive\48083_20240214150011919.zip" };
需求说明
需要从archivedFiles中筛选出文件名以仅存在于remotePatientsIDs、但不存在于localPatientsIDs的patientID开头的文件,最终结果应包含4个目标文件(如题目给出的预期结果)。
错误尝试及问题
- 以下代码无法编译:
List<string> archivedFilesToUnzip = archivedFiles.Where(name => name.Contains(remotePatientsIDs.Except(localPatientsIDs))).ToList();
报错信息:CS1503: Argument 1: cannot convert from 'System.Collections.Generic.IEnumerable<string>' to 'string'
原因:string.Contains()需要传入单个字符串参数,但Except返回的是字符串集合,类型不匹配。
- 以下代码始终返回空列表:
List<string> archivedFilesToUnzip = archivedFiles.Where(name => archivedFiles.Any(x => x.ToString().Contains(remotePatientsIDs.Except(localPatientsIDs).ToString()))).ToList();
原因:对集合调用ToString()得到的是集合的类型名称(而非集合内的元素),所以Contains判断永远不成立,结果为空。
正确LINQ实现
// 先获取目标patientID集合:仅在remote存在、不在local存在的ID,转HashSet提升查询效率 var targetPatientIds = new HashSet<string>(remotePatientsIDs.Except(localPatientsIDs)); // 筛选符合条件的归档文件 var archivedFilesToUnzip = archivedFiles .Where(filePath => { // 提取文件名中_之前的patientID部分 var fileName = Path.GetFileName(filePath); var patientId = fileName.Split('_')[0]; return targetPatientIds.Contains(patientId); }) .ToList();
代码说明
- 先用
Except得到remotePatientsIDs中不在localPatientsIDs里的ID集合,转成HashSet<string>是因为HashSet的Contains查询效率远高于List,数据量大时优势明显。 - 对每个文件路径,先用
Path.GetFileName获取纯文件名,再通过Split('_')[0]提取开头的patientID(题目明确文件名以patientID开头、后跟下划线)。 - 判断提取出的patientID是否在目标集合中,符合条件的文件会被保留。
内容的提问来源于stack exchange,提问作者fabricioLima
相关产品推荐
相关产品推荐

