考试判分场景下,如何用LINQ重构对比答案数组的循环代码?
用LINQ重构考试判分代码的方案
在学生考试判分的场景里,我们需要对比正确答案和学生答案两个字符数组,找出答错的题目并展示题号、正确答案及学生选项。你一开始用循环实现了这个功能,现在想改用LINQ重构,而且已经排除了.Except、.Union和.Intersect——确实,这些都是集合级别的对比操作,没法帮我们关联每个题目的位置和对应答案,完全不适合当前需求。
先回顾下你原来的循环实现和输出:
初始循环代码:
void Main() { char[] correctAnswer ="ACBCDABCABDDCCBA".ToCharArray(); char[] studentsChoice = "ABBCDDBCAADDACCA".ToCharArray(); for( int x = 0; x<=correctAnswer.Count()-1;x++) { if( ! correctAnswer[x].Equals(studentsChoice[x])) { Console.WriteLine(String.Format("Question:{0} correctAnswer:{1} StudentsChoice:{2}",x, correctAnswer[x],studentsChoice[x])); } } }
输出结果:
题号:1 正确答案:C 学生答案:B 题号:5 正确答案:A 学生答案:D 题号:9 正确答案:B 学生答案:A 题号:12 正确答案:C 学生答案:A 题号:14 正确答案:B 学生答案:C
适合的LINQ操作符
这里最适合的是**Zip搭配Where和Select**,这三个操作符组合起来刚好能完成我们的需求:
重构后的代码
void Main() { char[] correctAnswers = "ACBCDABCABDDCCBA".ToCharArray(); char[] studentChoices = "ABBCDDBCAADDACCA".ToCharArray(); // 用LINQ筛选出答错的题目 var incorrectQuestions = correctAnswers // 把两个数组同位置的答案配对 .Zip(studentChoices, (correct, student) => new { CorrectAnswer = correct, StudentChoice = student }) // 带上索引,转成从1开始的题号 .Select((answerPair, index) => new { QuestionNumber = index + 1, answerPair.CorrectAnswer, answerPair.StudentChoice }) // 过滤出答案不匹配的项 .Where(q => q.CorrectAnswer != q.StudentChoice); // 输出结果 foreach (var question in incorrectQuestions) { Console.WriteLine($"题号:{question.QuestionNumber} 正确答案:{question.CorrectAnswer} 学生答案:{question.StudentChoice}"); } }
代码说明
Zip:核心作用是将两个数组中对应位置的元素一一配对,生成包含正确答案和学生答案的匿名对象,这一步解决了循环中按索引取元素的逻辑。Select:这里利用了带索引的重载版本,把数组的索引(从0开始)转换成符合常规习惯的题号(从1开始),同时把配对的答案整理成更清晰的结构。Where:负责筛选出正确答案和学生答案不一致的题目,对应原循环里的if判断逻辑。
运行这段代码后,输出结果和你原来的完全一致,而且代码更简洁、可读性更强,完全符合LINQ的声明式编程风格。
如果想一次性输出所有结果而不用遍历,还可以用String.Join来简化:
var resultText = string.Join(Environment.NewLine, incorrectQuestions.Select(q => $"题号:{q.QuestionNumber} 正确答案:{q.CorrectAnswer} 学生答案:{q.StudentChoice}")); Console.WriteLine(resultText);
内容的提问来源于stack exchange,提问作者Tinypond
相关产品推荐
相关产品推荐

