1

アイテムのリストがあります。2つのプロパティの差が最小のアイテムを選択する必要があります。

例: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;

1つのステートメントでそれを達成できますか?このようにすることのパフォーマンスはどうなるでしょうか?楽観的だろう

4

4 に答える 4

4

を使用Math.Absして絶対差を取得し、それに従って順序付けて、最初の差を取ることができます。

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

最高のパフォーマンスが必要な場合MinByは、SkeetsMoreLinqを使用する必要があります。私のアプローチでは、差が最も小さいアイテムを取得する前に、すべてのアイテムを値で並べ替える必要があります。

最小の差を持つすべての学生を選択する必要がある場合、つまり、同じ最小の差を持つ複数の学生がいる場合はどうなりますか。

次に、使用できます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

2つを組み合わせるだけでいいと思います。

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の場合、ラムダ全体がSQLに変換されるため、パフォーマンスが向上します。

于 2012-08-20T12:21:06.023 に答える
0

MoreLinqにはMinBy関数とMaxBy関数があります。

これをさらに単純化するために、Studentsオブジェクトにプロパティを追加することをお勧めします

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

追加のプロパティは、データグリッドにバインドしたり、集計したりすることができます。減算を追加する必要はありません。

次に、Jon SkeetのMinByを使用して、次のように記述します。

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