1

我有一个项目清单。我必须选择两个属性之间差异最小的项目。

例如:Student { string Name, int ScoredMarks, int TotalMarks } 注意:所有学生的总分不会相同。我必须选择 TotalMarks 和 ScoredMarks 差异最小的学生。我能够这样做

int minDiff = students.Min(x => (x.TotalMarks - x.ScoredMarks));
var result = from s in students
             where s.TotalMarks - s.ScoredMarks == minDiff
             select s;

我可以在一个声明中实现它吗?这样做会有什么表现?这将是乐观的

4

4 回答 4

4

您可以使用Math.Abs获得绝对差异,按它排序并取第一个。

Student minDiff = students
        .OrderBy(x => Math.Abs(x.TotalMarks - x.ScoredMarks))
        .FirstOrDefault();
if(minDiff != null)
{
     // ...
}

如果你想要最好的性能,你应该使用MinBySkeets MoreLinq。我的方法需要先按价值对所有项目进行排序,然后才能采用差异最小的项目。

如果我必须选择所有具有最小差异的学生,即如果我有多个具有相同最小差异的学生怎么办。

然后你可以使用GroupBy

var minDiffGroup = students
            .GroupBy(x => Math.Abs(x.TotalMarks - x.ScoredMarks))
            .OrderBy(g => g.Key)
            .FirstOrDefault();
foreach(Student student in minDiffGroup)
{
    // ...
}
于 2012-08-20T12:19:49.460 回答
0

尝试这个:

Student TheOne = StudentList.OrderBy<Student, int>(x => x.TotalMarks - x.ScoredMarks).First<Student>();
于 2012-08-20T12:20:25.663 回答
0

我认为您可以将两者结合起来。

var result = from s in students
             where s.TotalMarks - s.ScoredMarks == students.Min(x => (x.TotalMarks - x.ScoredMarks))
             select s;

不过需要注意的是,这取决于您要查询的内容,这决定了这是一个“更好”的解决方案性能。如果是 linq-to-objects,则每次都运行 student.Min(...),这是一个更差的性能。如果是Entity Framework,则将整个lambda转换为SQL,这是一个更好的性能。

于 2012-08-20T12:21:06.023 回答
0

MoreLinq具有 MinBy 和 MaxBy 函数:

为了进一步简化这一点,我建议向您的学生对象添加一个属性

public int PriorTotalMarks { get { return this.TotalMarks - this.ScoredMarks; } }

附加属性可以绑定到数据网格、聚合等。没有额外的减法复杂性。

然后,使用 Jon Skeet 的 MinBy,您只需编写:

Students.MinBy(s => s.PriorTotalMarks);
于 2012-08-20T12:51:29.900 回答