Flattening a List หมายถึงการแปลง List<List<T>> ให้กลายเป็น List<T> เช่น การแปลง List<List<int>> ให้เป็น List<int>
SelectMany ใน LINQ ใช้สำหรับ Project แต่ละ Element ของ Sequence ให้เป็น IEnumerable<T> แล้ว Flatten Sequence ที่ได้ทั้งหมดรวมเป็น Sequence เดียว หมายความว่า SelectMany Operator รวม Record จาก Sequence ของ Results แล้วแปลงให้เป็น Result เดียว
ใช้ SelectMany (Method Syntax)
using System;
using System.Collections.Generic;
using System.Linq;
namespace DemoApplication {
public class Program {
static void Main(string[] args) {
List<List<int>> listOfNumLists = new List<List<int>> {
new List<int> { 1, 2 },
new List<int> { 3, 4 }
};
var numList = listOfNumLists.SelectMany(i => i);
Console.WriteLine("Numbers in the list:");
foreach(var num in numList) {
Console.WriteLine(num);
}
Console.ReadLine();
}
}
}
Output
Numbers in the list:
1
2
3
4
ใช้ Query Syntax
using System;
using System.Collections.Generic;
using System.Linq;
namespace DemoApplication {
public class Program {
static void Main(string[] args) {
List<List<int>> listOfNumLists = new List<List<int>> {
new List<int> { 1, 2 },
new List<int> { 3, 4 }
};
var numList = from listOfNumList in listOfNumLists
from value in listOfNumList
select value;
Console.WriteLine("Numbers in the list:");
foreach(var num in numList) {
Console.WriteLine(num);
}
Console.ReadLine();
}
}
}
ตัวอย่างขั้นสูง: Flatten Complex Objects
public class Department {
public string Name { get; set; }
public List Employees { get; set; }
}
public class Employee {
public string Name { get; set; }
public decimal Salary { get; set; }
}
var departments = new List {
new Department { Name = "IT", Employees = new List {
new Employee { Name = "John", Salary = 50000 },
new Employee { Name = "Jane", Salary = 60000 }
}},
new Department { Name = "HR", Employees = new List {
new Employee { Name = "Bob", Salary = 45000 }
}}
};
// Flatten เพื่อได้ Employee ทั้งหมด
var allEmployees = departments.SelectMany(d => d.Employees);
// หรือ SelectMany พร้อม Result Selector
var employeeInfos = departments.SelectMany(
d => d.Employees,
(dept, emp) => new { Department = dept.Name, Employee = emp.Name, emp.Salary }
);
foreach (var e in employeeInfos) {
Console.WriteLine($"{e.Department} - {e.Employee}: {e.Salary:C}");
}
SelectMany vs Select
| Method | Input | Output |
|---|---|---|
Select | List<List<T>> | IEnumerable<List<T>> |
SelectMany | List<List<T>> | IEnumerable<T> (Flattened) |
การจัดการ Null Collections
// ป้องกัน NullReferenceException
var safeFlatten = listOfNumLists?
.Where(list => list != null)
.SelectMany(list => list)
?? Enumerable.Empty();