如何用LINQ筛选List<VogueRec>中KEY长度小于10的元素并生成新列表
筛选VogueRec列表中KEY长度小于10的项的最优方式
问题描述
我有一个每行包含5个制表符分隔列的文件,已定义公共类VogueRec,每个列对应类的公共字符串属性。现需使用LINQ找出第五列(对应VogueRec的KEY属性)字符串长度小于10的行,并将查询结果填充到新的List<VogueRec>中。以下是已实现的文件读取代码,生成了List<VogueRec>类型的lsCorrel列表,请问完成上述筛选并生成新List的最优方式是什么?
定义的实体类
class VogueRec { public string DOMAIN { get; set; }//0 public string CLASSNAME { get; set; } //1 public string CLASS { get; set; }//2 public string KEYNAME { get; set; }//3 public string KEY { get; set; }//4 }
已实现的文件读取代码
var lsCorrel = new List<VogueRec>(); using (StreamReader sr = new StreamReader(fs)) { while ((sData = sr.ReadLine()) != null) { if ((sData.IndexOf("\t")) == -1) sData = sr.ReadLine();//跳过编码页行,忽略第一行 else { #region 读取USER数据 aSplit = sData.Split('\t'); while (aSplit[1] == "USER") { if (aSplit[3] != "CITY") { if (aSplit[3].IndexOf("CIT") == 0 || aSplit[3].IndexOf("VOICE") == 0) { lsCorrel.Add(new VogueRec() { DOMAIN = aSplit[0], CLASS = aSplit[2], KEYNAME = aSplit[3], KEY = aSplit[4].Substring(Math.Max(0, aSplit[4].Length - 5)) }); } } break; } #endregion } } } var result = lsCorrel.Where(v => v.KEY.Length < 10);
解决方案
方式一:基于已有列表直接筛选
你当前的Where查询返回的是IEnumerable<VogueRec>,并非List类型。要生成目标列表,只需调用ToList()方法即可,同时建议添加空值判断避免空引用异常:
// 生成筛选后的List,?.处理KEY为null的情况 var filteredList = lsCorrel.Where(v => v.KEY?.Length < 10).ToList();
如果业务场景中KEY不可能为null,可以简化为:
var filteredList = lsCorrel.Where(v => v.KEY.Length < 10).ToList();
方式二:读取时直接筛选(内存优化)
如果处理的是大文件,先加载所有数据再筛选会占用较多内存。更优的方式是在读取文件时直接过滤,只保留符合条件的项:
var filteredList = new List<VogueRec>(); using (StreamReader sr = new StreamReader(fs)) { string sData; while ((sData = sr.ReadLine()) != null) { // 跳过无制表符的行,同时处理读取到文件末尾的情况 if (sData.IndexOf("\t") == -1) { sData = sr.ReadLine(); if (sData == null) break; } string[] aSplit = sData.Split('\t'); // 简化原有的嵌套判断逻辑 if (aSplit[1] == "USER" && aSplit[3] != "CITY") { if (aSplit[3].StartsWith("CIT") || aSplit[3].StartsWith("VOICE")) { string key = aSplit[4].Substring(Math.Max(0, aSplit[4].Length - 5)); // 提前判断KEY长度,符合条件才添加到列表 if (key.Length < 10) { filteredList.Add(new VogueRec() { DOMAIN = aSplit[0], CLASS = aSplit[2], KEYNAME = aSplit[3], KEY = key }); } } } } }
这种方式避免了先存储全量数据,能有效降低内存占用,适合处理大型文件。
内容的提问来源于stack exchange,提问作者herba
相关产品推荐
相关产品推荐

