Select
และWhere
วิธีการที่มีอยู่ใน Linq นักพัฒนาทุกคนควรรู้อะไรเกี่ยวกับสองวิธีนี้บ้าง? ตัวอย่างเช่น: เมื่อใดควรใช้อย่างอื่นข้อดีของการใช้อย่างอื่นเป็นต้น
Select
และWhere
วิธีการที่มีอยู่ใน Linq นักพัฒนาทุกคนควรรู้อะไรเกี่ยวกับสองวิธีนี้บ้าง? ตัวอย่างเช่น: เมื่อใดควรใช้อย่างอื่นข้อดีของการใช้อย่างอื่นเป็นต้น
คำตอบ:
ที่ไหน
ค้นหารายการที่ตรงกันและส่งคืนเฉพาะรายการที่ทำ (การกรอง )
-> IEnumerable<A>
เข้าIEnumerable<A>
ออก
เลือก
ส่งคืนบางสิ่งสำหรับรายการทั้งหมดในแหล่งที่มา (การฉายภาพ / การแปลง ) บางสิ่งบางอย่างอาจเป็นของตัวเอง แต่มักจะเป็นการฉายภาพบางประเภท
-> IEnumerable<A>
เข้าIEnumerable<B>
ออก
Select
จะส่งคืนองค์ประกอบจำนวนเท่ากันในรายการเสมอ (ไม่ว่าคุณจะมีเงื่อนไขตัวกรองใดก็ตาม) Where
สามารถคืนค่าองค์ประกอบได้น้อยขึ้นอยู่กับเงื่อนไขตัวกรองของคุณ
Where == filter
และSelect == map
เลือกและตัวดำเนินการสองตัวที่แตกต่างกันโดยสิ้นเชิงที่ทำหน้าที่บนIEnumerable อยู่ที่ไหน s
ตัวแรกคือสิ่งที่เราเรียกว่าProjection Operatorในขณะที่ตัวสุดท้ายคือไฟล์ผู้ดำเนินการข้อ จำกัด
วิธีหนึ่งที่น่าสนใจในการทำความเข้าใจพฤติกรรมของตัวดำเนินการดังกล่าวคือการดูที่ "ประเภทการทำงาน"
เลือก: (IEnumerable <T1>, Func <T1, T2>) → IEnumerable <T2> ; ใช้เป็นอินพุตทั้ง IEnumerable ที่มีอิลิเมนต์ประเภท T1 และฟังก์ชันเปลี่ยนอิลิเมนต์ประเภท T1 เป็นอิลิเมนต์ประเภท T2 เอาต์พุตเป็น IEnumerable ที่มีองค์ประกอบประเภท T2
จากนี้เราสามารถคาดเดาได้อย่างง่ายดายว่าตัวดำเนินการนี้จะสร้างเอาต์พุตโดยใช้ฟังก์ชันอินพุตกับแต่ละองค์ประกอบของอินพุต IE ที่ไม่สามารถคำนวณได้และรวมผลลัพธ์ไว้ใน IEnumerable ใหม่
การใช้สัญกรณ์ที่เหมือนคณิตศาสตร์จะใช้เป็นอินพุต(a, b, c, ... ): IEnumerable <T1>และf: T1 → T2และสร้าง(f (a), f (b), f (c) , ... ): IEnumerable <T2>
ที่ไหน: (IEnumerable <T1>, Func <T1, bool>) → IEnumerable <T1> ; อันนี้ใช้ IEnumerable ที่มีอิลิเมนต์ประเภท T1 และเพรดิเคตบน T1 (นั่นคือฟังก์ชันที่สร้างผลลัพธ์บูลีนสำหรับอินพุตประเภท T1) คุณจะเห็นว่าเอาต์พุตยังเป็น IEnumerable ที่มีอิลิเมนต์ประเภท T1
คราวนี้เราจะเดาได้ว่าองค์ประกอบของอินพุต IEnumerable จะมีอยู่ในเอาต์พุต IEnumerable ขึ้นอยู่กับผลลัพธ์ของการประยุกต์ใช้เพรดิเคตกับองค์ประกอบ การเพิ่มความหมายของชื่อตัวดำเนินการนี้คุณสามารถมั่นใจได้ว่าจะสร้างผลลัพธ์ที่ IE ไม่สามารถคำนวณได้โดยรับจากอินพุตเพียงองค์ประกอบเดียวที่ประเมินว่าเป็นจริงในการประยุกต์ใช้เพรดิเคต
ผู้ที่มีการเขียนโปรแกรมเชิงฟังก์ชันพื้นฐานมักจะคิดเช่นนี้ ช่วยให้คุณสามารถอนุมาน (หรืออย่างน้อยก็เดา ... ) ว่าตัวดำเนินการทำอะไรโดยดูจากประเภทเท่านั้น!
ลองดูตัวดำเนินการอื่น ๆ ที่แนะนำโดย LINQ บน IEnumerables และสรุปพฤติกรรมของพวกเขาก่อนที่จะดูเอกสาร!
มีความแตกต่างกัน:
Select
เป็นเรื่องเกี่ยวกับการเปลี่ยนแปลง
Where
เป็นเรื่องเกี่ยวกับการกรอง
เลือกแมปแจกแจงกับโครงสร้างใหม่ หากคุณทำการเลือกบน IEnumerable คุณจะได้อาร์เรย์ที่มีองค์ประกอบจำนวนเท่ากัน แต่จะเป็นประเภทที่แตกต่างกันขึ้นอยู่กับการแมปที่คุณระบุ โดยที่จะกรอง IEnumerable เพื่อให้คุณเป็นส่วนย่อยของ IEnumerable ดั้งเดิม
Where
~ = ตัวกรอง
Select
~ = แผนที่
ผลตอบแทนทั้งสอง IEnumerable<T>
หากคุณรู้ว่าพวกเขาใช้ที่ไหนและเลือกวิธีการขยายคุณสามารถคาดเดาได้ว่ากำลังทำอะไรอยู่ ... ฉันพยายามนำไปใช้ที่ไหนและเลือกวิธีการขยาย ... คุณสามารถดูได้ ...
สถานที่ดำเนินการ ::
public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<Tsource> a , Func<Tsource , bool> Method )
{
foreach ( var data in a )
{
//If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
if ( Method.Invoke ( data ) )
{
yield return data;
}
}
}
เลือกการใช้งาน ::
public static IEnumerable<TResult> Select<TSource , TResult> ( this IEnumerable<TSource> a , Func<TSource , TResult> Method )
{
foreach ( var item in a )
{
//Each iteration call the delegate and return the Data back.(use 'yield' for deferred return)
yield return Method.Invoke ( item );
}
}
การใช้งานของฉันทำงานได้ดีสำหรับคอลเลกชันใด ๆ ... แต่แตกต่างจากวิธีการส่วนขยายที่ใช้งานของ Microsoft เนื่องจากใช้แผนภูมินิพจน์เพื่อใช้งานแบบเดียวกัน
ในกรณีของ Select it คุณสามารถจับคู่โครงสร้างใหม่กับ IE ได้
A.Select(x=>new X{UID=x.uid, UNAME=x.uname})
//input as [IEnumerable<A>] --------> return output as [IEnumerable<X> ]
โดยที่ () ทำงานเป็นตัวกรองไปยัง IEnumerable มันจะส่งคืนผลลัพธ์บนพื้นฐานของ where clause
A.Where(x=>x.uid!=0) //input as [IEnumerable<A>] --------> return output as [IEnumerable<A> ]