พระคัมภีร์การใช้คำสั่ง LINQ

🤔 คำสั่งของ LINQ ที่ได้ใช้บ่อยๆมีไรบ้างนะ

บทความนี้เป็นบทความที่แยกออกมาจากเรื่อง LINQ ซึ่งเป็นหนึ่งในคำสั่งเทพเจ้าของสาย .NET ซึ่งมันจะทำให้ developer ทำงานได้สบายลงแบบฝุดๆ ดังนั้นใครยังไม่รู้เรื่อง LINQ ให้กลับไปอ่านบทความนี้ก่อนเน่อ Saladpuk - LINQ 101

Filtering Data

Where - เป็นการเลือกเอาเฉพาะข้อมูลที่เราสนใจออกมา เช่น มี data source เป็นเลข 1~100 แล้วต้องการเอาเฉพาะเลขที่ 5 และ 7 หารลงตัวออกมา ก็จะเขียนออกมาได้เป็นแบบนี้

var collection = Enumerable.Range(1, 100);
var qry = collection.Where(it => it % 5 == 0 && it % 7 == 0);
// ผลลัพท์: { 35, 70 }

Projection Operations

Select - เป็นการเลือกว่า data source ที่เราไปดึงข้อมูลมา เราจะดัดแปลงแก้ไข หรือ เลือกเอาเฉพาะข้อมูลบางส่วนออกมาใช้

เช่นมี collection เป็นเลข 1~5 ตอนที่เราจะเอามาทำงานด้วยเราจะแก้ให้มันถูก คูณด้วย 10 ก่อนค่อยเอามาใช้งาน ก็จะเขียนได้แบบนี้

var collection = new int[] { 1, 2, 3, 4, 5 };
var qry = collection.Select(it => it * 10);
// ผลลัพท์: { 10, 20, 30, 40, 50 }

หรือ จะให้มันเปลี่ยนเป็นข้อมูลอีกประเภทนึงเลยก็ได้

var qry = collection.Select(it => new Student{ Id = it });
public class Student
{
    public int Id { get; set; }
}

ส่วนถ้าข้อมูลใน data source มันวุ่นวายเกินไป เราก็สามารถเลือกแค่บางส่วนของมันมาใช้ก็ได้นะ เช่น เราอยากได้แค่ Name ที่อยู่ใน collection มาใช้เท่านั้น ก็เขียนเป็นแบบนี้ได้

SelectMany - เป็นการเลือกเข้าไปถึงหน่วยย่อยของ collection ที่ซ้อนภายใน collection อีกทีนึง

แนะนำให้อ่าน คำสั่ง SelectMany สำหรับคนที่พึ่งหัดใช้ LINQ อาจจะ งงๆ หน่อยแต่ถ้าเราได้ทำงานร่วมกับพวก collection ซ้อน collection แล้วล่ะก็ควรจะทำความเข้าใจมันเอาไว้นะ ซึ่งอ่านได้จากลิงค์นี้เลย Microsoft document - Projection Operations

Element Operations

ในบางทีเราอยากจะทำงานกับข้อมูลแค่ตัวใดตัวหนึ่งหรือส่วนหนึ่งที่อยู่ใน collection เราก็สามารถใช้คำสั่งที่อยู่ด้านล่างได้ เช่น เรามี data source ที่มีข้อมูลเป็นเลข 1~100

First - เอาเฉพาะตัวแรกออกมา

FirstOrDefault - เหมือนกับ First ทุกประการ ต่างกันแค่ถ้ามันดึงค่าออกมาไม่ได้มันจะส่งค่า default ของ data type นั้นๆกลับมา

Last - เอาเฉพาะตัวสุดท้ายออกมา

LastOrDefault - เหมือนกับ Last ทุกประการ ต่างกันแค่ถ้ามันดึงค่าออกมาไม่ได้มันจะส่งค่า default ของ data type นั้นๆกลับมา

ElementAt - เป็นการดึงค่าที่อยู่ใน index ที่กำหนดออกมา

ElementAtOrDefault - เหมือนกับ ElementAt ทุกประการ ต่างกันแค่ถ้ามันดึงค่าออกมาไม่ได้มันจะส่งค่า default ของ data type นั้นๆกลับมา

Partitioning Data

เวลาที่เราทำงานกับ data source ปริมาณมากๆ เราสามารถที่จะทำการแบ่งข้อมูลออกเป็นส่วนๆ เพื่อให้ง่ายในการทำงานได้ เช่น มี collection ตัวเลข 1~100 อยู่ตามด้านล่าง

Take - เป็นการสั่งให้ดึงข้อมูลจาก data source ออกมาเท่าที่เรากำหนดไว้ เช่น เราอยากดึงข้อมูลมาแค่ 5 ตัวแรกก่อน เราก็จะเขียนได้ว่า

TakeLast - เหมือนกับ Take แต่จะดึงมาจากด้านหลังสุด เช่น อยากจะดึงข้อมูล 5 ตัวจากด้านหลังสุดออกมา

TakeWhile - เป็นการสั่งให้มันดึงข้อมูลจาก data source ออกมาเรื่อยๆจนกว่าจะเจอตัวแรกที่ทำให้เงื่อนไขไม่เป็นจริง เช่น ให้ดึงมาเรื่อยๆถ้าเลขที่ดึงมามันยังน้อยกว่า 8

Skip - สั่งให้ข้ามข้อมูลเท่ากับที่เรากำหนด เช่น เราต้องการข้ามข้อมูล 4 ตัวแรกไป

SkipLast - เหมือนกับ Skip ต่างกันแค่มันจะข้ามเฉพาะตัวด้านหลังสุด เช่น อยากจะข้ามข้อมูล 4 ตัวสุดท้ายไป

SkipWhile - เป็นการสั่งให้มันข้ามข้อมูลไปเรื่อยๆ ถ้าเงื่อนไขยังเป็นจริงอยู่ และจะหยุดข้ามเมื่อเจอข้อมูลตัวแรกที่ไม่ตรงเงื่อนไข เช่น อยากจะข้ามไปเรื่อยๆจนกว่าจะเจอตัวแรกที่มากกว่า 50

Set Operations

เราสามารถทำงานกับ data source ที่เป็น 2 กลุ่มให้มาทำงานร่วมกันได้ 3 แบบคือ

เช่นเรามีข้อมูลกลุ่ม a กับกลุ่ม b เป็นแบบนี้

Intersect - ตามรูปเลยคือ เอาเฉพาะที่มันเหมือนกันออกมา

Union - ตามรูปเลยคือ เอาทั้งสองกลุ่มมารวมกัน

Except - ตามรูปเลยคือ เอาเฉพาะของที่ไม่ซ้ำกับอีกกลุ่มออกมา

Distinct - เป็นการตัดตัวซ้ำทิ้ง

Sorting Data

การเรียงลำดับเราทำได้ 3 แบบ น้อยไปมาก มากไปน้อย และ กลับด้านข้อมูล เช่นเรามี data source เป็นแบบนี้

OrderBy - เรียงลำดับจากน้อยไปมาก หรือถ้าเป็นตัวอักษรจะเป็นการเรียงจาก a~Z

OrderByDescending - เรียงลำดับจากมากไปน้อย

Reverse - เรียงลำดับแบบกลับด้าน ขวาไปซ้าย แทน

ThenBy และ ThenByDescending - แต่ถ้าข้อมูลมีความซับซ้อนมากขึ้น เราสามารถกำหนดความสำคัญในการเรียงลำดับได้ด้วย เช่น เรียงลำดับจากคะแนนน้อยไปมาก แต่ถ้าคะแนนเท่ากันให้เรียงจากชื่อตามลำดับตัวอักษรก็จะเขียนแบบนี้ได้

Quantifier Operations

เราสามารถหาผลลัพท์จากข้อมูลใน collection ได้เช่น มีบางตัวไหม? หรือ ทุกตัวเป็นแบบนี้ไหม? อาจจะฟังแล้ว งงๆ ไปดูตัวอย่างเลยดีกว่า โดยสมมุติว่าผมมี data source เป็นแบบนี้

Any - ถามว่ามีซักตัวไหมที่เป็นแบบนี้ เช่น อยากรู้ว่ามีซักตัวไหมใน collection ที่มีค่ามากกว่า 9 ก็สามารถเขียนเป็น

All - ถามว่าทุกตัวเป็นแบบนี้หรือเปล่า เช่น อยากเช็คว่าทุกตัวใน collection มากกว่า 5 หรือเปล่า

Contains - ถามว่าภายในนั้นมีตัวนี้อยู่หรือเปล่า เช่น collection นั้นมีเลข 8 อยู่ในนั้นหรือเปล่า

Grouping Data

GroupBy - สั่งให้มันจัดกลุ่มของข้อมูลได้ เช่น มี collection ของคนหลายๆคน แล้วเราอยากให้จัดกลุ่มคนตามอายุ เราก็จะเขียนได้ว่า

Generation Operations

ถ้าเราต้องการสร้างข้อมูลที่เป็น collection ขึ้นมาแบบง่ายๆ เราก็สามารถใช้ LINQ ช่วยสร้างได้

Range - สร้างชุดตัวเลขออกมา เช่น อยากได้ collection ตัวเลขตั้งแต่ 1 ถึง 100

Empty - สร้าง collection ว่างออกมา เช่น เราอยากได้ collection ของตัวเลข แต่ไม่ต้องมีข้อมูลอะไรอยู่ข้างในนะ

DefaultIfEmpty - ถ้าเราต้องไปทำงานกับ collection ตัวเลขซักตัว แต่ถ้า collection นั้นมันเป็นค่าว่าง เราจะกำหนดค่า 9 ให้มันไปใช้แทน

Repeat - สร้างชุดข้อมูลซ้ำๆกันออกมา เช่น อยากได้ collection เลข 5 ซ้ำกัน 3 ตัว ก็เขียนแบบนี้ได้

Converting Data Types

เราสามารถแปลง data source ของเราจาก data type นึงไปยังอีก data type นึงก็ได้นะ เช่น มีข้อมูล collection เลข 1~5 ตามนี้

AsEnumerable - แปลงให้มันกลับมาเป็น IEnumerable<T> เอาไว้ช่วยแปลงจาก collection อะไรก็ตามให้กลับมาสู่ base class ของกลุ่ม collection

AsQueryable - แปลงให้คำสั่งทั้งหมดยังเป็นแค่ Query เท่านั้น ซึ่งใช้ได้ดีตอนที่ทำงานร่วมกับ database เพราะเราจะได้ส่งแต่คำสั่งไปประมวลผลที่ database เท่านั้นไม่ได้ส่งข้อมูลปริมาณมหาศาลกลับมาถล่มที่ client

Cast - แปลงข้อมูลจาก data source ให้กลายเป็น data type ที่กำหนด

OfType - เลือกเอาเฉพาะ data type ที่ตรงกับที่กำหนด

ToArray - แปลงให้ collection นั้นๆกลายเป็น Array

ToList - แปลงให้ collection นั้นๆกลายเป็น List

ToDictionary - แปลงให้ collection นั้นๆกลายเป็น Dictionary<K, V> เช่นทำการจัดกลุ่มว่าใครเรียนอยู่ห้องไหนบ้าง แล้วทำการไปสร้างเป็น dictionary

Concatenation Operations

Concate - เป็นการเอา 2 collection มาต่อกันแบบดื้อๆเลย

Aggregation Operations

เป็นกลุ่มคำสั่งที่ได้ผลลัพท์กลับมาเลย และเป็นการทำงานแบบ Imperative เช่นมี data source เป็นเลข 1~10 ตามนี้

Sum - หาผลรวม

Average - หาค่าเฉลี่ย

Max - หาค่าสูงสุด

Min - หาค่าต่ำสุด

Count - นับว่าภายใน data source มีข้อมูลอยู่ทั้งหมดเท่าไหร่

Aggregate - นำข้อมูลทั้ง collection มาดำเนินการแบบต่อเนื่องกัน

แนะนำให้อ่าน คำสั่ง Aggregate ถ้าเราใช้เป็นจริงๆมันทรงพลังมากเลยนะ ลองศึกษาเพิ่มเติมได้จากลิงค์นี้เบย Microsoft document - Aggregation

บทสรุป Deferred vs Imperative

จากคำสั่งทั้งหมดที่เขียนมาเป็นตัวอย่าง สุดท้ายการทำงานของมันก็จะตกมาอยู่ในกลุ่ม 3 กลุ่มนั่นเองคือ

  • ทำงานโดยทันที Immediate

  • ไม่ทำงานจนกว่าจะเรียกใช้ Deferred

    • ดึงข้อมูลทั้งหมดมาก่อนค่อยทำงาน Non-Streaming

    • ค่อยทะยอยดึงข้อมูลมาเรื่อยๆ Streaming

Last updated

Was this helpful?