我需要从studentid列表中查找不包含值的记录。没有1:1匹配字段。记录包含3个关键字段,根据条件,我必须与学生列表进行比较。
例如:如果rawdata记录有非空的studentnumber值,那么我必须将studentnumber和sequencenumber连接起来,并检查该组合是否存在于studentid列表中。否则,我必须连接EnrollNumber和SequenceNumber。
我正在尝试在包含中使用三元运算符,如下所示,
var studentIDs = students.Select(x => x.StudentID).Distinct().ToList();
var rawData = StudentManager.GetAllData();
var resultList = rawData.Where(x => !studentIDs.Contains($"{(!string.IsNullOrWhiteSpace(x.StudentNumber)? (x.StudentNumber+x.SequenceNumber):(x.EnrollNumber+x.SequenceNumber))}")).ToList();
然而,对于更大的数据集(超过5K(,速度似乎越来越慢。任何关于替代方法或改进方式的建议都将不胜感激。特别是,如果Contains中的代码(三元运算符(可以简化。
正如@derpischer在推荐中提到的,你尝试过哈希集吗?
将第一行替换为以下内容:
var studentIDs = new HashSet<string>(students.Select(x => x.StudentID));
这将加快您的执行时间。请告诉我它是否有效。
我认为您的逻辑方法很好。我认为你可以用一种更清晰、更容易的方式来呈现它。考虑以下内容:
HashSet<string> studentIDs = students.Select(s => s.StudentID)
.ToHashSet();
string StudentID(RawDataStudent s) => string.IsNullOrWhiteSpace(s.StudentNumber)
? $"{s.EnrollNumber}{s.SequenceNumber}"
: $"{s.StudentNumber}{s.SequenceNumber}";
var rawData = StudentManager.GetAllData();
var resultList = rawData.Where(s => !studentIDs.Contains(StudentID(s)))
.ToList();
要点:
- 取出整个"contains"lambda,并将其作为一个命名清晰的函数显示出来,具有良好的可读性
- 总是试着用布尔值做肯定的运算——特别是你最终得到了这个带有null或空白的奇怪括号否定,只需切换返回值——同样也更容易阅读
- 正如其他海报所评论的那样,对HashSet调用contains会快得多
- 注意,我假设您的GetAllData返回类型是var有点邪恶的一个很好的例子