Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

วิธี Flatten List ด้วย LINQ ใน C#

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

MethodInputOutput
SelectList<List<T>>IEnumerable<List<T>>
SelectManyList<List<T>>IEnumerable<T> (Flattened)

การจัดการ Null Collections

// ป้องกัน NullReferenceException
var safeFlatten = listOfNumLists?
    .Where(list => list != null)
    .SelectMany(list => list)
    ?? Enumerable.Empty();