firstWhere() ใน Laravel Collections — หาข้อมูลตัวแรกตามเงื่อนไข
ทำไมต้อง firstWhere()?
เวลาที่มีข้อมูลเยอะๆ แล้วต้องการหา “ตัวแรก” ที่ตรงเงื่อนไข หลายคนมักจะใช้ filter()->first() ซ้อนกัน แต่ Laravel มี method ที่ทำสิ่งนี้โดยเฉพาะ นั่นคือ firstWhere()
firstWhere() สั้นกว่า, อ่านง่ายกว่า และทำงานเร็วกว่า เพราะมันหยุดหลังจากเจอข้อมูลตัวแรกที่ตรงเงื่อนไขทันที
🔧 วิธีใช้งาน
Syntax พื้นฐาน
$collection->firstWhere($key, $operator, $value);
Parameters:
| Parameter | ความหมาย |
|---|---|
$key |
key ที่ใช้เปรียบเทียบ |
$operator |
เครื่องหมายเปรียบเทียบ (เช่น =, >, <, >=, <=) |
$value |
ค่าที่ต้องการเปรียบเทียบ |
รูปแบบที่ 1: เช็คเท่ากับ (Default)
$products = collect([
['name' => 'iPhone', 'price' => 29900, 'stock' => 10],
['name' => 'Samsung', 'price' => 24900, 'stock' => 0],
['name' => 'OPPO', 'price' => 12900, 'stock' => 25],
['name' => 'Xiaomi', 'price' => 9990, 'stock' => 50],
]);
// หาสินค้าที่ราคา 24900 (เท่ากับ)
$product = $products->firstWhere('price', '=', 24900);
// Result: ['name' => 'Samsung', 'price' => 24900, 'stock' => 0]
// เขียนแบบย่อ (default operator คือ '=')
$product = $products->firstWhere('price', 24900);
// Result: ['name' => 'Samsung', 'price' => 24900, 'stock' => 0]
รูปแบบที่ 2: เปรียบเทียบมากกว่า/น้อยกว่า
// หาสินค้าที่ราคามากกว่า 20000
$expensive = $products->firstWhere('price', '>', 20000);
// Result: ['name' => 'iPhone', 'price' => 29900, 'stock' => 10]
// หาสินค้าที่ราคาน้อยกว่า 15000
$cheap = $products->firstWhere('price', '<', 15000);
// Result: ['name' => 'OPPO', 'price' => 12900, 'stock' => 25]
// หาสินค้าที่ stock มากกว่าหรือเท่ากับ 20
$inStock = $products->firstWhere('stock', '>=', 20);
// Result: ['name' => 'OPPO', 'price' => 12900, 'stock' => 25]
รูปแบบที่ 3: ใช้กับ string
$users = collect([
['name' => 'สมชาย', 'role' => 'admin', 'active' => true],
['name' => 'สมหญิง', 'role' => 'editor', 'active' => true],
['name' => 'วิชัย', 'role' => 'admin', 'active' => false],
['name' => 'สมศักดิ์', 'role' => 'viewer', 'active' => true],
]);
// หาผู้ใช้ที่มี role เป็น admin
$admin = $users->firstWhere('role', 'admin');
// Result: ['name' => 'สมชาย', 'role' => 'admin', 'active' => true]
// หาผู้ใช้ที่ active เป็น true
$active = $users->firstWhere('active', true);
// Result: ['name' => 'สมชาย', 'role' => 'admin', 'active' => true]
รูปแบบที่ 4: กรณีไม่เจอข้อมูล
// ถ้าไม่เจอ จะคืนค่า null
$notFound = $products->firstWhere('price', 99999);
// Result: null
// กำหนดค่า default ได้ (Laravel 8+)
$notFound = $products->firstWhere('price', 99999, 'ไม่พบสินค้า');
// Result: 'ไม่พบสินค้า'
📌 ตัวอย่างใช้งานจริง
ตัวอย่างที่ 1: หาสินค้าที่กำลังลดราคา
$discountedProducts = collect([
['id' => 1, 'name' => 'เสื้อยืด', 'original_price' => 590, 'sale_price' => 390],
['id' => 2, 'name' => 'กางเกงยีนส์', 'original_price' => 1290, 'sale_price' => 890],
['id' => 3, 'name' => 'รองเท้าผ้าใบ', 'original_price' => 1990, 'sale_price' => 1490],
]);
// หาสินค้าที่ลดราคาเกิน 50%
$bestDeal = $discountedProducts->firstWhere(function ($product) {
$discount = ($product['original_price'] - $product['sale_price']) / $product['original_price'];
return $discount > 0.5;
});
// Result: ['id' => 1, 'name' => 'เสื้อยืด', 'original_price' => 590, 'sale_price' => 390]
ตัวอย่างที่ 2: หาผู้ใช้ที่อนุมัติแล้วจากรายการ
$orders = collect([
['order_id' => 'ORD001', 'customer' => 'ลูกค้า A', 'status' => 'pending'],
['order_id' => 'ORD002', 'customer' => 'ลูกค้า B', 'status' => 'approved'],
['order_id' => 'ORD003', 'customer' => 'ลูกค้า C', 'status' => 'pending'],
['order_id' => 'ORD004', 'customer' => 'ลูกค้า D', 'status' => 'shipped'],
]);
// หาออเดอร์แรกที่ approved
$approvedOrder = $orders->firstWhere('status', 'approved');
// Result: ['order_id' => 'ORD002', 'customer' => 'ลูกค้า B', 'status' => 'approved']
ตัวอย่างที่ 3: ใช้กับ Eloquent
// ดึง collection จาก Eloquent แล้วใช้ firstWhere
$users = User::all();
$activeAdmin = $users->firstWhere('role', 'admin');
// หรือ query แล้วใช้ chain
$user = User::where('active', true)->get()->firstWhere('department', 'IT');
📌 firstWhere() vs filter()->first()
$products = collect([
['name' => 'A', 'price' => 100],
['name' => 'B', 'price' => 200],
['name' => 'C', 'price' => 200],
]);
// ใช้ filter()->first() — ทำงาน 2 steps
$result1 = $products->filter(fn($p) => $p['price'] === 200)->first();
// Result: ['name' => 'B', 'price' => 200]
// ใช้ firstWhere() — ทำงาน 1 step
$result2 = $products->firstWhere('price', 200);
// Result: ['name' => 'B', 'price' => 200]
// ✅ firstWhere() ดีกว่าเพราะ:
// 1. Code สั้นและอ่านง่ายกว่า
// 2. อ่านเป็นภาษาธรรมชาติมากกว่า "หาตัวแรกที่ price = 200"
// 3. Performance ดีกว่า (หยุดเมื่อเจอตัวแรกทันที)
📌 สรุป
firstWhere() เป็น method ที่ทำให้การหาข้อมูลตัวแรกตามเงื่อนไขทำได้ง่ายและอ่านง่าย ต้องจำว่า:
- ใช้
firstWhere($key, $value)สำหรับเช็คเท่ากับ - ใช้
firstWhere($key, $operator, $value)สำหรับเปรียบเทียบอื่นๆ - ถ้าไม่เจอ จะคืน
null(หรือค่า default ที่กำหนดได้) - ใช้
firstWhere()แทนfilter()->first()เสมอ เพราะสั้นกว่าและทำงานเร็วกว่า
จำไว้ว่า method นี้เหมาะกับการหา “ตัวแรกที่ตรงเงื่อนไข” ถ้าต้องการหาทุกตัวที่ตรงเงื่อนไข ให้ใช้ where() แทนนะครับ