在lamba表达式中的contains内部使用三元运算符



我需要从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有点邪恶的一个很好的例子

最新更新