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

การหาค่าน้อยที่สุดในอาร์เรย์ด้วย Lambda Expression ใน C#

เมธอด Min() ใน LINQ รองรับ Lambda Expression (Selector) เพื่อเลือกคุณสมบัติหรือคำนวณค่าก่อนหาค่าน้อยที่สุด เหมาะสำหรับอาร์เรย์ของ Object หรือการแปลงค่าก่อนเปรียบเทียบ

รูปแบบการใช้งาน

int[] arr = { 10, 15, 5, 20 };
int min = arr.Min(x => Math.Abs(x)); // หาค่าสัมบูรณ์ที่น้อยที่สุด

โค้ดตัวอย่างสมบูรณ์

using System;
using System.Linq;

class Demo
{
    static void Main()
    {
        int[] arr = { 10, 15, 5, 20 };
        
        Console.WriteLine("อาร์เรย์: " + string.Join(", ", arr));
        Console.WriteLine($"Min() ปกติ: {arr.Min()}"); // 5
        Console.WriteLine($"Min(x => Math.Abs(x)): {arr.Min(x => Math.Abs(x))}"); // 5
        
        // ตัวอย่าง: ค่าลบ
        int[] withNegative = { -10, 15, -5, 20 };
        Console.WriteLine($"\nอาร์เรย์มีค่าลบ: {string.Join(", ", withNegative)}");
        Console.WriteLine($"Min() ปกติ: {withNegative.Min()}"); // -10
        Console.WriteLine($"Min(Math.Abs): {withNegative.Min(x => Math.Abs(x))}"); // 5
        
        // ตัวอย่างกับ Object
        Console.WriteLine("\n--- กับ Object ---");
        var products = new[]
        {
            new { Name = "A", Price = 100, Stock = 5 },
            new { Name = "B", Price = 50, Stock = 0 },
            new { Name = "C", Price = 200, Stock = 10 }
        };
        
        Console.WriteLine($"ราคาต่ำสุด: {products.Min(p => p.Price)}"); // 50
        Console.WriteLine($"สต็อกต่ำสุด: {products.Min(p => p.Stock)}"); // 0
        
        // MinBy (.NET 6+) - คืน Object ทั้งตัว
        var cheapest = products.MinBy(p => p.Price);
        Console.WriteLine($"สินค้าราคาถูกสุด: {cheapest.Name} = {cheapest.Price}");
        
        // Complex Selector
        Console.WriteLine("\n--- Complex Selector ---");
        string[] words = { "apple", "banana", "cat", "dog", "elephant" };
        Console.WriteLine($"ความยาวสั้นสุด: {words.Min(w => w.Length)}"); // 3
        Console.WriteLine($"ตัวอักษรแรกน้อยสุด: {words.Min(w => w[0])}"); // 'a' (ASCII 97)
    }
}

ผลลัพธ์

อาร์เรย์: 10, 15, 5, 20
Min() ปกติ: 5
Min(x => Math.Abs(x)): 5

อาร์เรย์มีค่าลบ: -10, 15, -5, 20
Min() ปกติ: -10
Min(Math.Abs): 5

--- กับ Object ---
ราคาต่ำสุด: 50
สต็อกต่ำสุด: 0
สินค้าราคาถูกสุด: B = 50

--- Complex Selector ---
ความยาวสั้นสุด: 3
ตัวอักษรแรกน้อยสุด: a

Min() Overloads

Overloadคำอธิบายตัวอย่าง
Min()ค่าน้อยที่สุดของ Element โดยตรงnumbers.Min()
Min(selector)Select ค่า/Property แล้วหา Minpeople.Min(p => p.Age)
MinBy(selector).NET 6+ คืน Element ที่มีค่าน้อยสุดpeople.MinBy(p => p.Age)

การใช้งานกับชนิดข้อมูลต่างๆ

// Numeric
double minDouble = doubles.Min();
decimal minDecimal = decimals.Min();

// DateTime
DateTime earliest = dates.Min();

// TimeSpan
TimeSpan shortest = durations.Min();

// String (Lexicographic - พจนานุกรม)
string firstAlphabetically = words.Min(); // "apple" < "banana"

// Nullable Types
int?[] nullable = { 5, null, 3, null, 10 };
int? minNullable = nullable.Min(); // 3 (ข้าม null)
int minNonNull = nullable.Where(x => x.HasValue).Min(x => x.Value); // 3

MinBy (.NET 6+) - คืน Object ทั้งตัว

var cheapestProduct = products.MinBy(p => p.Price);
// cheapestProduct = { Name = "B", Price = 50, Stock = 0 }

// หลายเกณฑ์ (Tuple)
var youngestThenCheapest = people.MinBy(p => (p.Age, p.Salary));

ข้อควรระวัง

  • ลำดับว่าง → โยน InvalidOperationException - ใช้ DefaultIfEmpty() หรือ MinBy() (คืน null)
  • Selector ควรคืนค่าที่ Comparable (implement IComparable)
  • สำหรับ String: ใช้ Lexicographic Order (ตัวอักษร) ไใช่ความยาว
  • MinBy คืนค่า null หากลำดับว่าง (ปลอดภัยกว่า Min)

การป้องกัน Exception ลำดับว่าง

// วิธี 1: DefaultIfEmpty
int min = arr.DefaultIfEmpty(int.MaxValue).Min();

// วิธี 2: MinBy (คืน null)
var minObj = arr.MinBy(x => x); // null หากว่าง

// วิธี 3: Ternary
int min = arr.Any() ? arr.Min() : 0;