เมธอด 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 แล้วหา Min | people.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;