การจัดกลุ่มรายการในหน่วยความจำใน C# ด้วย LINQ และนิพจน์ Lambda
เมื่อทำงานกับรายการใน C# คุณอาจพบกับหลายสถานการณ์ที่คุณต้องจัดกลุ่มรายการตามคุณสมบัติที่เฉพาะเจาะจง สำหรับตัวอย่าง สมมติว่าคุณมีคอลเลกชันของวัตถุ Foo
และคุณต้องการจัดระเบียบตามค่าของคุณสมบัติ Bar
นี่คือจุดที่พลังของ LINQ (Language Integrated Query) และนิพจน์ lambda จะมีบทบาท ในบล็อกโพสต์นี้ เราจะสำรวจวิธีการจัดกลุ่มรายการในหน่วยความจำโดยใช้ฟีเจอร์เหล่านี้ของ C# อย่างมีประสิทธิภาพ
การทำความเข้าใจปัญหา
ลองนึกภาพว่าคุณมีรายการของวัตถุ Foo
ซึ่งแต่ละ Foo
มีคุณสมบัติ Bar
และ Lum
บางอินสแตนซ์ของ Foo
อาจแชร์ค่าที่เหมือนกันสำหรับ Bar
เป้าหมายของคุณคือการจัดกลุ่มอินสแตนซ์ Foo
เหล่านี้ตามค่าของ Bar
และหลังจากนั้นวนซ้ำผ่านคอลเลกชันที่จัดกลุ่มเพื่อเข้าถึงค่าของ Lum
ที่สอดคล้องกัน นี่สามารถปรับปรุงการจัดระเบียบข้อมูลและทำให้สะดวกต่อการจัดการเซ็ตข้อมูลที่เฉพาะเจาะจงมากขึ้น
ตัวอย่างสถานการณ์
ลองพิจารณาตัวอย่างเฉพาะด้วยรายการของอินสแตนซ์ Foo
ดังต่อไปนี้:
var foos = new List<Foo> {
new Foo{Bar = 1,Lum = 1},
new Foo{Bar = 1,Lum = 2},
new Foo{Bar = 2,Lum = 3},
};
ผลลัพธ์ที่ต้องการ
เราต้องการจัดกลุ่มอินสแตนซ์ Foo
เหล่านี้ตามค่าของ Bar
โดยสุดท้ายจะผลิตสิ่งที่คล้ายกับ:
- สำหรับ
Bar = 1
:Lum = 1
,Lum = 2
- สำหรับ
Bar = 2
:Lum = 3
วิธีแก้ปัญหาด้วย LINQ
คุณสามารถจัดกลุ่มวัตถุ Foo
โดยใช้คำสั่ง group by
ของ LINQ นี่คือวิธีการที่ทำได้:
var groupedFoos = from foo in foos
group foo by foo.Bar into grouped
let lums = from g in grouped
select g.Lum
select new { Bar = grouped.Key, Lums = lums };
ขั้นตอนที่อธิบาย
- Group By: ส่วน
group foo by foo.Bar
จะจัดกลุ่มอินสแตนซ์Foo
ตามคุณสมบัติBar
- Into Grouped: สิ่งนี้สร้างขอบเขตใหม่สำหรับแต่ละกลุ่ม
- การเลือกค่า Lum: คำสั่ง
let lums
ช่วยให้คุณสร้างคอลเลกชันใหม่ที่ประกอบด้วยค่าจากวัตถุที่จัดกลุ่ม - การเลือกขั้นสุดท้าย: การเลือกขั้นสุดท้ายจะรวบรวมทุกอย่างเป็นวัตถุใหม่ที่มีค่า
Bar
และรายการค่าของLum
ที่สอดคล้องกัน
วิธีแก้ปัญหาด้วยนิพจน์ Lambda
อีกทางเลือกหนึ่ง คุณสามารถทำให้เกิดผลลัพธ์เดียวกันโดยใช้นิพจน์ lambda ซึ่งสามารถเสนอไวยากรณ์ที่กระชับมากขึ้น นี่คือวิธีการ:
var groupedFoos = foos.GroupBy(x => x.Bar)
.Select(y => new { Bar = y.Key, Lums = y.Select(z => z.Lum) });
วิธีการทำงาน
- GroupBy: วิธีนี้รับฟังก์ชัน lambda เพื่อตั้งค่าคุณสมบัติที่เราต้องการจะจัดกลุ่ม โดยเฉพาะอย่างยิ่ง
x.Bar
- Select: หลังจากการจัดกลุ่มแล้ว เราจะใช้
Select
เพื่อสร้างวัตถุที่ไม่ระบุชื่อใหม่สำหรับแต่ละกลุ่ม ซึ่งมีBar
และค่าของLum
ที่สอดคล้องกัน
การวนซ้ำผ่านข้อมูลที่จัดกลุ่ม
ไม่ว่าคุณจะใช้ LINQ หรือนิพจน์ lambda การวนซ้ำผ่านข้อมูลที่จัดกลุ่มยังคงเหมือนเดิม คุณสามารถวนซ้ำแต่ละกลุ่มและพิมพ์ค่าของ Lum
ได้ดังนี้:
foreach (var group in groupedFoos)
{
Console.WriteLine("Lums for Bar#" + group.Bar);
foreach (var lum in group.Lums)
{
Console.WriteLine(lum);
}
}
เอาท์พุตจะเป็น:
Lums for Bar#1
1
2
Lums for Bar#2
3
บทสรุป
การจัดกลุ่มรายการในหน่วยความจำโดยใช้ LINQ หรือนิพจน์ lambda ใน C# เป็นวิธีที่ทรงพลังในการจัดระเบียบข้อมูลของคุณ ไม่ว่าคุณจะชอบความอ่านง่ายของไวยากรณ์ LINQ หรือความกระชับของนิพจน์ lambda วิธีทั้งสองจะช่วยให้คุณสามารถบรรลุการจัดกลุ่มข้อมูลที่ต้องการได้อย่างมีประสิทธิภาพ
สำหรับผู้ที่ต้องการขยายความเข้าใจเกี่ยวกับ LINQ แนะนำให้สำรวจ 101 LINQ Samples เพื่อดูตัวอย่างที่ครอบคลุมเพิ่มเติม
หากคุณมีคำถามหรืออยากจะแบ่งปันประสบการณ์เกี่ยวกับการจัดกลุ่มข้อมูลใน C# โปรดอย่าลังเลที่จะทิ้งความคิดเห็นด้านล่าง!