วิธีใช้ LINQ เพื่อเลือกวัตถุที่มีค่าคุณสมบัติขั้นต่ำหรือสูงสุด


466

ฉันมีวัตถุบุคคลที่มีคุณสมบัติ DateOfBirth Nullable มีวิธีการใช้ LINQ ในการค้นหารายการของวัตถุบุคคลสำหรับหนึ่งที่มีค่า DateOfBirth เร็วที่สุด / เล็กที่สุด

นี่คือสิ่งที่ฉันเริ่มต้นด้วย:

var firstBornDate = People.Min(p => p.DateOfBirth.GetValueOrDefault(DateTime.MaxValue));

ค่า Null DateOfBirth ถูกตั้งค่าเป็น DateTime.MaxValue เพื่อที่จะตัดออกจากการพิจารณาขั้นต่ำ (สมมติว่าอย่างน้อยหนึ่งตัวมี DOB ที่ระบุ)

แต่สิ่งที่ทำเพื่อฉันคือการตั้งค่า firstBornDate เป็นค่า DateTime สิ่งที่ฉันต้องการได้คือวัตถุบุคคลที่ตรงกับที่ ฉันต้องเขียนคำถามที่สองเช่นนี้หรือไม่:

var firstBorn = People.Single(p=> (p.DateOfBirth ?? DateTime.MaxValue) == firstBornDate);

หรือมีวิธีการที่บางกว่าหรือไม่?


24
เพียงแสดงความคิดเห็นในตัวอย่างของคุณ: คุณอาจไม่ควรใช้ซิงเกิลที่นี่ มันจะโยนข้อยกเว้นถ้าคนสองคนมี DateOfBirth เดียวกัน
Niki

1
ดูเพิ่มเติมstackoverflow.com/questions/2736236/…ที่ซ้ำกันเกือบทั้งหมดซึ่งมีตัวอย่างที่กระชับ
goodeye

4
อะไรคือคุณสมบัติที่เรียบง่ายและมีประโยชน์ MinBy ควรอยู่ในไลบรารี่มาตรฐาน เราควรส่งคำขอดึงไปยัง Microsoft github.com/dotnet/corefx
Colonel Panic

2
สิ่งนี้ดูเหมือนจะมีอยู่ในปัจจุบันเพียงแค่ให้ฟังก์ชั่นในการเลือกอสังหาริมทรัพย์:a.Min(x => x.foo);
jackmott

4
เพื่อแสดงปัญหา: ใน Python ให้max("find a word of maximal length in this sentence".split(), key=len)ส่งคืนสตริง 'ประโยค' ใน C # "find a word of maximal length in this sentence".Split().Max(word => word.Length)คำนวณว่า 8 คือความยาวที่ยาวที่สุดของคำใด ๆ แต่ไม่ได้บอกคุณว่าคำที่ยาวที่สุดคืออะไร
พันเอก Panic

คำตอบ:


299
People.Aggregate((curMin, x) => (curMin == null || (x.DateOfBirth ?? DateTime.MaxValue) <
    curMin.DateOfBirth ? x : curMin))

16
อาจช้ากว่าการใช้ IComparable เล็กน้อยและใช้ Min (หรือ a for loop) แต่ +1 สำหรับโซลูชัน linqy O (n)
Matthew Flaschen

3
นอกจากนี้ยังต้องเป็น <curmin.DateOfBirth มิฉะนั้นคุณกำลังเปรียบเทียบ DateTime กับบุคคล
Matthew Flaschen

2
ระวังเมื่อใช้สิ่งนี้เพื่อเปรียบเทียบสองวันที่ ฉันใช้สิ่งนี้เพื่อค้นหาบันทึกการเปลี่ยนแปลงล่าสุดในคอลเล็กชันที่ไม่ได้เรียงลำดับ มันล้มเหลวเพราะบันทึกที่ฉันต้องการจบลงด้วยวันและเวลาเดียวกัน
Simon Gill

8
ทำไมคุณถึงตรวจสอบฟุ่มเฟือยcurMin == null? curMinเพียง แต่อาจจะเป็นnullว่าคุณกำลังใช้เมล็ดพันธุ์ที่เป็นAggregate() null
ราตรีสวัสดิ์ Nerd Pride


226

น่าเสียดายที่ไม่มีวิธีการติดตั้งในตัว แต่ก็ง่ายพอที่จะทำให้คุณได้ นี่คือความกล้าของมัน:

public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source,
    Func<TSource, TKey> selector)
{
    return source.MinBy(selector, null);
}

public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source,
    Func<TSource, TKey> selector, IComparer<TKey> comparer)
{
    if (source == null) throw new ArgumentNullException("source");
    if (selector == null) throw new ArgumentNullException("selector");
    comparer = comparer ?? Comparer<TKey>.Default;

    using (var sourceIterator = source.GetEnumerator())
    {
        if (!sourceIterator.MoveNext())
        {
            throw new InvalidOperationException("Sequence contains no elements");
        }
        var min = sourceIterator.Current;
        var minKey = selector(min);
        while (sourceIterator.MoveNext())
        {
            var candidate = sourceIterator.Current;
            var candidateProjected = selector(candidate);
            if (comparer.Compare(candidateProjected, minKey) < 0)
            {
                min = candidate;
                minKey = candidateProjected;
            }
        }
        return min;
    }
}

ตัวอย่างการใช้งาน:

var firstBorn = People.MinBy(p => p.DateOfBirth ?? DateTime.MaxValue);

โปรดทราบว่าสิ่งนี้จะทำให้เกิดข้อยกเว้นหากลำดับนั้นว่างเปล่าและจะส่งคืนองค์ประกอบแรกที่มีค่าน้อยที่สุดหากมีมากกว่าหนึ่งรายการ

หรือคุณสามารถใช้การดำเนินการที่เราได้มีในMoreLINQในMinBy.cs (มีMaxByแน่นอนที่สอดคล้องกัน)

ติดตั้งผ่านคอนโซลตัวจัดการแพคเกจ:

PM> การติดตั้งแพคเกจ morelinq


1
ผมจะเข้ามาแทนที่ IEnumerator + ในขณะที่มี foreach
ggf31416

5
ไม่สามารถทำได้อย่างง่ายดายเนื่องจากการเรียกครั้งแรกไปยัง MoveNext () ก่อนการวนซ้ำ มีทางเลือก แต่พวกเขากำลังยุ่ง IMO
Jon Skeet

2
ในขณะที่ฉันสามารถคืนค่าเริ่มต้น (T) ที่รู้สึกไม่เหมาะสมกับฉัน สิ่งนี้สอดคล้องกับวิธีการเช่น First () และวิธีการของตัวทำดัชนีพจนานุกรม คุณสามารถปรับเปลี่ยนได้อย่างง่ายดายหากคุณต้องการ
Jon Skeet

8
ฉันได้รับคำตอบให้กับ Paul เนื่องจากวิธีแก้ปัญหาที่ไม่ใช่ห้องสมุด แต่ขอขอบคุณสำหรับรหัสนี้และลิงก์ไปยังห้องสมุด MoreLINQ ซึ่งฉันคิดว่าฉันจะเริ่มใช้!
slolife


135

หมายเหตุ: ฉันรวมคำตอบนี้เพื่อความสมบูรณ์เนื่องจาก OP ไม่ได้กล่าวถึงแหล่งข้อมูลและเราไม่ควรตั้งสมมติฐานใด ๆ

แบบสอบถามนี้ให้คำตอบที่ถูกต้อง แต่อาจช้าลงเนื่องจากอาจต้องเรียงลำดับรายการทั้งหมดตามPeopleโครงสร้างข้อมูลPeople:

var oldest = People.OrderBy(p => p.DateOfBirth ?? DateTime.MaxValue).First();

อัปเดต: ที่จริงฉันไม่ควรเรียกโซลูชันนี้ว่า "ไร้เดียงสา" แต่ผู้ใช้ไม่จำเป็นต้องรู้ว่าเขากำลังสอบถามอะไรอยู่ "ความเชื่องช้า" ของโซลูชันนี้ขึ้นอยู่กับข้อมูลพื้นฐาน หากนี่คืออาร์เรย์หรือList<T>จากนั้น LINQ ไปยังวัตถุไม่มีตัวเลือกนอกจากเรียงลำดับการรวบรวมทั้งหมดก่อนที่จะเลือกรายการแรก ในกรณีนี้มันจะช้ากว่าโซลูชันอื่นที่แนะนำ อย่างไรก็ตามหากนี่เป็นตาราง LINQ ไปยัง SQL และDateOfBirthเป็นคอลัมน์ที่จัดทำดัชนีไว้ SQL Server จะใช้ดัชนีแทนการเรียงลำดับแถวทั้งหมด IEnumerable<T>การใช้งานที่กำหนดเองอื่น ๆยังสามารถใช้ดัชนี (ดูi4o: ดัชนี LINQหรือฐานข้อมูลวัตถุdb4o ) และทำให้การแก้ปัญหานี้เร็วกว่าAggregate()หรือMaxBy()/MinBy()ซึ่งต้องย้ำการเก็บทั้งหมดครั้งเดียว ในความเป็นจริง LINQ to Objects อาจมี (ในทางทฤษฎี) ทำกรณีพิเศษOrderBy()สำหรับคอลเลกชันเรียงเช่นSortedList<T>แต่มันไม่เท่าที่ฉันรู้


1
มีคนโพสต์แล้ว แต่เห็นได้ชัดว่าลบหลังจากที่ฉันแสดงความคิดเห็นว่าช้า (และใช้พื้นที่มาก) มันเป็น (O (n log n) ความเร็วที่ดีที่สุดเมื่อเทียบกับ O (n) เป็นนาที :)
Matthew Flaschen

ใช่เหตุเตือนของฉันเกี่ยวกับการเป็นวิธีการแก้ปัญหาไร้เดียงสา :) แต่มันเป็นตายง่ายและอาจจะสามารถใช้งานได้ในบางกรณี (คอลเลกชันขนาดเล็กหรือถ้า DateOfBirth เป็นคอลัมน์ DB จัดทำดัชนี)
ลูคัส

อีกกรณีพิเศษ (ซึ่งไม่มีอยู่ด้วย) คือมันจะเป็นไปได้ที่จะใช้ความรู้ในการสั่งซื้อและก่อนที่จะทำการค้นหาค่าต่ำสุดโดยไม่ต้องเรียงลำดับ
Rune FS

การเรียงลำดับคอลเล็กชันคือการดำเนินการ Nlog (N) ซึ่งไม่ได้ดีไปกว่าความซับซ้อนเชิงเส้นหรือ O (n) เวลา ถ้าเราต้องการเพียง 1 องค์ประกอบ / วัตถุจากลำดับซึ่งเป็น min หรือ max ฉันคิดว่าเราควรจะยึดติดอยู่กับ Linear time comlexity
Yawar Murtaza

@yawar คอลเลกชันอาจถูกเรียงลำดับแล้ว (จัดทำดัชนีมีแนวโน้มมากกว่า) ซึ่งในกรณีนี้คุณสามารถมี O (บันทึก n)
Rune FS

63
People.OrderBy(p => p.DateOfBirth.GetValueOrDefault(DateTime.MaxValue)).First()

จะทำเคล็ดลับ


1
อันนี้ดีมาก! ฉันใช้กับ OrderByDesending (... ) ใช้ (1) ในกรณีของ linq projetion
Vedran Mandić

1
อันนี้ใช้การเรียงลำดับซึ่งเกินเวลา O (N) และใช้หน่วยความจำ O (N)
George Polevoy

@ GeorgePolevoy ที่ถือว่าเรารู้ค่อนข้างมากเกี่ยวกับแหล่งข้อมูล หากแหล่งข้อมูลมีดัชนีที่เรียงลำดับอยู่ในเขตข้อมูลที่กำหนดไว้แล้วนี่จะเป็นค่าคงที่ (ต่ำ) และมันจะเร็วกว่าคำตอบที่ยอมรับซึ่งต้องผ่านรายการทั้งหมด หากแหล่งข้อมูลในอีกทางหนึ่งเป็นเช่นอาร์เรย์คุณมีสิทธิ์
Rune FS

@RuneFS - ยังคุณควรพูดถึงในคำตอบของคุณเพราะมันเป็นสิ่งสำคัญ
rory.ap

ประสิทธิภาพจะลากคุณลง ฉันเรียนรู้มันอย่างหนัก หากคุณต้องการวัตถุที่มีค่าต่ำสุดหรือสูงสุดคุณไม่จำเป็นต้องเรียงลำดับอาร์เรย์ทั้งหมด การสแกนเพียง 1 ครั้งก็เพียงพอแล้ว ดูคำตอบที่ยอมรับหรือดูแพคเกจ MoreLinq
Sau001

35

ดังนั้นคุณจะขอหรือArgMin ArgMaxC # ไม่มี API ในตัวสำหรับสิ่งเหล่านั้น

ฉันกำลังมองหาวิธีที่สะอาดและมีประสิทธิภาพ (O (n)) และฉันคิดว่าฉันพบหนึ่ง:

รูปแบบทั่วไปของรูปแบบนี้คือ:

var min = data.Select(x => (key(x), x)).Min().Item2;
                            ^           ^       ^
              the sorting key           |       take the associated original item
                                Min by key(.)

พิเศษใช้ตัวอย่างในคำถามเดิม:

สำหรับ C # 7.0 และสูงกว่าที่รองรับtuple ค่า :

var youngest = people.Select(p => (p.DateOfBirth, p)).Min().Item2;

สำหรับรุ่น C # ก่อน 7.0 คุณสามารถใช้ประเภทไม่ระบุชื่อแทน:

var youngest = people.Select(p => new { ppl = p; age = p.DateOfBirth }).Min().ppl;

พวกเขาทำงานเพราะทั้งสอง tuple มูลค่าและประเภทที่ไม่ระบุชื่อมี comparers เริ่มต้นที่เหมาะสม: สำหรับ (x1, y1) และ (x2, y2) มันเป็นครั้งแรกเปรียบเทียบx1เทียบx2แล้วเทียบกับy1 y2นั่นเป็นสาเหตุที่ทำให้.Minสามารถใช้งานบิวด์อินกับประเภทเหล่านั้นได้

และเนื่องจากทั้งประเภทที่ไม่ระบุชื่อและค่า tuple เป็นประเภทค่าจึงควรมีประสิทธิภาพมาก

บันทึก

ในข้างต้นของฉัน ArgMinการใช้งานฉันฉันคิดว่าDateOfBirthจะใช้ประเภทDateTimeเพื่อความเรียบง่ายและชัดเจน คำถามเดิมขอให้ยกเว้นรายการเหล่านั้นด้วยDateOfBirthฟิลด์null :

ค่า Null DateOfBirth ถูกตั้งค่าเป็น DateTime.MaxValue เพื่อที่จะตัดออกจากการพิจารณาขั้นต่ำ (สมมติว่าอย่างน้อยหนึ่งตัวมี DOB ที่ระบุ)

มันสามารถทำได้ด้วยการกรองล่วงหน้า

people.Where(p => p.DateOfBirth.HasValue)

ดังนั้นมันจึงไม่มีสาระสำคัญสำหรับคำถามของการนำไปใช้ ArgMinArgMaxหรือ

โน้ต 2

วิธีการข้างต้นมีข้อแม้ว่าเมื่อมีสองอินสแตนซ์ที่มีค่าขั้นต่ำเท่ากันดังนั้นMin()การนำไปใช้จะพยายามเปรียบเทียบอินสแตนซ์เป็น tie-breaker อย่างไรก็ตามหากคลาสของอินสแตนซ์ไม่ได้ใช้งานIComparableข้อผิดพลาดรันไทม์จะถูกส่งออกไป:

วัตถุอย่างน้อยหนึ่งรายการต้องใช้ IComparable

โชคดีที่สิ่งนี้สามารถแก้ไขได้ค่อนข้างเรียบร้อย แนวคิดคือการเชื่อมโยง "ID" ที่ผิดเพี้ยนกับแต่ละรายการที่ทำหน้าที่เป็น tie-breaker ที่ไม่น่าสงสัย เราสามารถใช้ ID ที่เพิ่มขึ้นสำหรับแต่ละรายการ ยังคงใช้อายุผู้คนเป็นตัวอย่าง:

var youngest = Enumerable.Range(0, int.MaxValue)
               .Zip(people, (idx, ppl) => (ppl.DateOfBirth, idx, ppl)).Min().Item3;

1
สิ่งนี้ดูเหมือนจะไม่ทำงานเมื่อประเภทของมูลค่าเป็นกุญแจในการเรียงลำดับ "วัตถุอย่างน้อยหนึ่งรายการต้องใช้ IComparable"
เหลียง

1
ยอดเยี่ยมเกินไป! นี่ควรเป็นคำตอบที่ดีที่สุด
Guido Mocha

@liang ใช่จับดี โชคดีที่ยังมีทางออกที่สะอาดอยู่ ดูโซลูชันที่อัปเดตในหัวข้อ "หมายเหตุ 2"
KFL

เลือกสามารถให้ ID! var youngest = people.Select ((p, i) => (p.DateOfBirth, i, p)) ขั้นต่ำ (). รายการ 2;
Jeremy

19

โซลูชันที่ไม่มีแพ็คเกจเพิ่มเติม:

var min = lst.OrderBy(i => i.StartDate).FirstOrDefault();
var max = lst.OrderBy(i => i.StartDate).LastOrDefault();

นอกจากนี้คุณสามารถห่อเป็นส่วนขยาย:

public static class LinqExtensions
{
    public static T MinBy<T, TProp>(this IEnumerable<T> source, Func<T, TProp> propSelector)
    {
        return source.OrderBy(propSelector).FirstOrDefault();
    }

    public static T MaxBy<T, TProp>(this IEnumerable<T> source, Func<T, TProp> propSelector)
    {
        return source.OrderBy(propSelector).LastOrDefault();
    }
}

และในกรณีนี้:

var min = lst.MinBy(i => i.StartDate);
var max = lst.MaxBy(i => i.StartDate);

โดยวิธีการ ... O (n ^ 2) ไม่ใช่ทางออกที่ดีที่สุด Paul Bettsให้วิธีแก้ปัญหาไขมันต่ำกว่าฉัน แต่ฉันยังคงเป็นโซลูชั่น LINQ และมันง่ายและสั้นกว่าโซลูชันอื่น ๆ ที่นี่


3
public class Foo {
    public int bar;
    public int stuff;
};

void Main()
{
    List<Foo> fooList = new List<Foo>(){
    new Foo(){bar=1,stuff=2},
    new Foo(){bar=3,stuff=4},
    new Foo(){bar=2,stuff=3}};

    Foo result = fooList.Aggregate((u,v) => u.bar < v.bar ? u: v);
    result.Dump();
}

3

การใช้การรวมที่เรียบง่ายอย่างสมบูรณ์แบบ (เทียบเท่ากับการพับในภาษาอื่น ๆ ):

var firstBorn = People.Aggregate((min, x) => x.DateOfBirth < min.DateOfBirth ? x : min);

ข้อเสียเพียงอย่างเดียวคือคุณสมบัติเข้าถึงสองครั้งต่อองค์ประกอบลำดับซึ่งอาจมีราคาแพง มันยากที่จะแก้ไข


1

ต่อไปนี้เป็นคำตอบทั่วไป โดยพื้นฐานแล้วมันทำสิ่งเดียวกัน (ตามลำดับ O (N)) แต่สำหรับ IEnumberable ทุกประเภทและสามารถผสมกับประเภทที่ตัวเลือกคุณสมบัติสามารถส่งคืนค่าว่างได้

public static class LinqExtensions
{
    public static T MinBy<T>(this IEnumerable<T> source, Func<T, IComparable> selector)
    {
        if (source == null)
        {
            throw new ArgumentNullException(nameof(source));
        }
        if (selector == null)
        {
            throw new ArgumentNullException(nameof(selector));
        }
        return source.Aggregate((min, cur) =>
        {
            if (min == null)
            {
                return cur;
            }
            var minComparer = selector(min);
            if (minComparer == null)
            {
                return cur;
            }
            var curComparer = selector(cur);
            if (curComparer == null)
            {
                return min;
            }
            return minComparer.CompareTo(curComparer) > 0 ? cur : min;
        });
    }
}

แบบทดสอบ:

var nullableInts = new int?[] {5, null, 1, 4, 0, 3, null, 1};
Assert.AreEqual(0, nullableInts.MinBy(i => i));//should pass

0

แก้ไขอีกครั้ง:

ขอโทษ นอกจากนี้ยังขาดโมฆะฉันมองไปที่ฟังก์ชั่นที่ไม่ถูกต้อง

ต่ำสุด <(จาก <(TSource, TResult>)>) (IEnumerable <(ของ <(TSource>)>>), Func <(จาก <(TSource, TResult>)>))จะส่งคืนประเภทผลลัพธ์ตามที่คุณพูด

ฉันจะบอกทางออกหนึ่งที่เป็นไปได้คือการใช้ IComparable และใช้Min <(ของ <(TSource>)>)) (IEnumerable <(Of <(TSource>)>))ซึ่งจริงๆแล้วจะส่งคืนองค์ประกอบจาก IEnumerable แน่นอนว่ามันไม่ได้ช่วยอะไรคุณหากคุณไม่สามารถแก้ไของค์ประกอบได้ ฉันพบว่าการออกแบบของ MS ดูแปลกที่นี่

แน่นอนคุณสามารถทำการวนซ้ำได้ตลอดเวลาหากคุณต้องการหรือใช้การติดตั้ง MoreLINQ ที่ Jon Skeet มอบให้


0

การใช้งานอื่นซึ่งสามารถทำงานกับคีย์ตัวเลือก null ได้และสำหรับการรวบรวมประเภทการอ้างอิงจะคืนค่า null หากไม่พบองค์ประกอบที่เหมาะสม สิ่งนี้อาจเป็นประโยชน์ในการประมวลผลผลลัพธ์ของฐานข้อมูลเป็นต้น

  public static class IEnumerableExtensions
  {
    /// <summary>
    /// Returns the element with the maximum value of a selector function.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
    /// <param name="source">An IEnumerable collection values to determine the element with the maximum value of.</param>
    /// <param name="keySelector">A function to extract the key for each element.</param>
    /// <exception cref="System.ArgumentNullException">source or keySelector is null.</exception>
    /// <exception cref="System.InvalidOperationException">source contains no elements.</exception>
    /// <returns>The element in source with the maximum value of a selector function.</returns>
    public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) => MaxOrMinBy(source, keySelector, 1);

    /// <summary>
    /// Returns the element with the minimum value of a selector function.
    /// </summary>
    /// <typeparam name="TSource">The type of the elements of source.</typeparam>
    /// <typeparam name="TKey">The type of the key returned by keySelector.</typeparam>
    /// <param name="source">An IEnumerable collection values to determine the element with the minimum value of.</param>
    /// <param name="keySelector">A function to extract the key for each element.</param>
    /// <exception cref="System.ArgumentNullException">source or keySelector is null.</exception>
    /// <exception cref="System.InvalidOperationException">source contains no elements.</exception>
    /// <returns>The element in source with the minimum value of a selector function.</returns>
    public static TSource MinBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) => MaxOrMinBy(source, keySelector, -1);


    private static TSource MaxOrMinBy<TSource, TKey>
      (IEnumerable<TSource> source, Func<TSource, TKey> keySelector, int sign)
    {
      if (source == null) throw new ArgumentNullException(nameof(source));
      if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
      Comparer<TKey> comparer = Comparer<TKey>.Default;
      TKey value = default(TKey);
      TSource result = default(TSource);

      bool hasValue = false;

      foreach (TSource element in source)
      {
        TKey x = keySelector(element);
        if (x != null)
        {
          if (!hasValue)
          {
            value = x;
            result = element;
            hasValue = true;
          }
          else if (sign * comparer.Compare(x, value) > 0)
          {
            value = x;
            result = element;
          }
        }
      }

      if ((result != null) && !hasValue)
        throw new InvalidOperationException("The source sequence is empty");

      return result;
    }
  }

ตัวอย่าง:

public class A
{
  public int? a;
  public A(int? a) { this.a = a; }
}

var b = a.MinBy(x => x.a);
var c = a.MaxBy(x => x.a);

-2

ฉันกำลังมองหาสิ่งที่คล้ายตัวเองโดยเฉพาะอย่างยิ่งโดยไม่ต้องใช้ห้องสมุดหรือเรียงลำดับรายการทั้งหมด วิธีการแก้ปัญหาของฉันจบลงคล้ายกับคำถามนั้นง่ายขึ้นเล็กน้อย

var firstBorn = People.FirstOrDefault(p => p.DateOfBirth == People.Min(p2 => p2.DateOfBirth));

มันจะไม่ได้มีประสิทธิภาพมากขึ้นที่จะได้รับนาทีก่อนที่คำสั่ง linq ของคุณ? var min = People.Min(...); var firstBorn = People.FirstOrDefault(p => p.DateOfBirth == min...มิฉะนั้นจะได้รับขั้นต่ำซ้ำ ๆ จนกระทั่งพบสิ่งที่คุณกำลังมองหา
Nieminen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.