Laravel Collections reject() Method: คู่มือฉบับสมบูรณ์

Laravel Collections reject() Method: คู่มือฉบับสมบูรณ์

สวัสดีครับนักพัฒนา Laravel ทุกท่าน! วันนี้เราจะมาพูดถึงหนึ่งใน methods ที่น่าสนใจของ Laravel Collections นั่นคือ reject() method ซึ่งเป็น “inverse” หรือตัวกลับด้านของ filter() นั่นเอง

บทนำ – Laravel Collections reject() คืออะไร?

Laravel Collections เป็น class ที่ช่วยให้เราจัดการกับ arrays ได้อย่างมีประสิทธิภาพ โดย reject() method เป็น method สำหรับกรองข้อมูลในลักษณะ “ตรงข้าม” กับ filter() คือ แทนที่จะเก็บรายการที่ผ่านเงื่อนไข reject() จะ ลบรายการที่ผ่านเงื่อนไขออก และเก็บเฉพาะรายการที่ไม่ผ่านเงื่อนไข

Laravel Collections reject() method - dark code editor with neon green highlights

ทำไมต้องใช้ reject()?

ลองนึกภาพว่าคุณมีรายการ users หลายพันรายการ และต้องการลบเฉพาะ users ที่เป็น admin ออก หรือต้องการลบสินค้าที่หมดสต็อกออกจากรายการ นี่คือจุดที่ reject() ทำให้ชีวิตเราง่ายขึ้น เพราะอ่านโค้ดแล้วเข้าใจได้ทันทีว่า “ต้องการลบอะไรออก”

$users = collect([
    ['name' => 'John', 'role' => 'user'],
    ['name' => 'Jane', 'role' => 'admin'],
    ['name' => 'Bob', 'role' => 'user'],
]);

// ลบ admin ออก - อ่านแล้วเข้าใจทันที
$nonAdmins = $users->reject(fn($user) => $user['role'] === 'admin');

ข้อดีของการใช้ reject()

  • โค้ดอ่านง่าย – “ลบออก” อ่านเข้าใจง่ายกว่า “เก็บที่ไม่เท่ากับ”
  • Method chaining – สามารถต่อ methods กันได้เรื่อยๆ
  • Immutable – คืนค่า collection ใหม่เสมอ ไม่แก้ไข collection ต้นฉบับ
  • Functional programming – เขียนโค้ดแบบ declarative แทน imperative

Basic Syntax – รูปแบบการใช้งาน reject()

รูปแบบพื้นฐาน

reject($callback = null)

Parameters:
$callback – closure ที่รับ $value และ $key (optional) และคืนค่า true ถ้าต้องการลบ item นั้นออก

Return: คืนค่าเป็น Collection ใหม่ที่มีเฉพาะ items ที่ไม่ถูก reject

reject() กับ Callback

เมื่อมี callback, items ที่ callback คืนค่า true จะถูกลบออก:

$collection = collect([1, 2, 3, 4, 5]);

// ลบเลขคู่ออก (2, 4)
$oddNumbers = $collection->reject(fn($item) => $item % 2 === 0);
// Result: [1, 3, 5]

reject() แบบไม่มี Callback (ลบ Falsy Values)

ถ้าไม่ระบุ callback, reject() จะลบค่า “falsy” ออกทั้งหมด (null, false, 0, '', []):

$collection = collect([1, 0, 'foo', null, false, '', 'bar']);

// ลบค่า falsy ออก
$clean = $collection->reject();
// Result: [1, 'foo', 'bar']

Callback รับ Value และ Key

Callback สามารถรับ parameter ทั้ง $value และ $key:

$collection = collect(['a' => 1, 'b' => null, 'c' => 3]);

// ลบ items ที่มี value เป็น null
$clean = $collection->reject(fn($value, $key) => is_null($value));
// Result: ['a' => 1, 'c' => 3]

reject() vs filter() – ความแตกต่าง

นี่คือหัวใจสำคัญที่หลายคนสับสน! reject() และ filter() เป็น “ตัวกลับด้าน” กัน:

reject() vs filter() comparison flowchart - Laravel Collections

Method เงื่อนไข ผลลัพธ์
filter() เก็บ items ที่ callback คืนค่า true รายการที่ต้องการ
reject() ลบ items ที่ callback คืนค่า true รายการที่ไม่ต้องการ

ตัวอย่างเปรียบเทียบ

$collection = collect([1, 2, 3, 4, 5]);

// filter() - เก็บเลขคู่ (callback คืน true สำหรับเลขคู่)
$evenWithFilter = $collection->filter(fn($n) => $n % 2 === 0);
// Result: [2, 4]

// reject() - ลบเลขคู่ออก (callback คืน true สำหรับเลขคู่)
$evenWithReject = $collection->reject(fn($n) => $n % 2 === 0);
// Result: [1, 3, 5]

// สังเกตว่า filter และ reject ใช้ callback เดียวกัน แต่ได้ผลลัพธ์ตรงข้ามกัน!

เมื่อไหร่ควรใช้ reject vs filter?

สถานการณ์ แนะนำใช้ เหตุผล
“ลบ users ที่ไม่ active ออก” filter() เขียน “เก็บ active” สื่อความหมายกว่า
“ลบ admin ออก” reject() อ่านแล้วเข้าใจทันทีว่าต้องการลบอะไร
“เก็บสินค้าราคาต่ำกว่า 100” filter() เน้น “เก็บ” สินค้าที่ต้องการ
“ลบสินค้าหมดสต็อกออก” reject() อ่านโค้ดแล้วเข้าใจง่ายกว่า

ตารางเปรียบเทียบ reject vs filter vs where vs contains

Method เงื่อนไข Callback จำเป็น? ใช้เมื่อ
reject() ลบเมื่อ return true ✅ ต้องมี ต้องการ “ลบ” รายการที่ไม่ต้องการ
filter() เก็บเมื่อ return true ✅ ต้องมี ต้องการ “เก็บ” รายการที่ตรงเงื่อนไข
where() เก็บเมื่อ key เท่ากับค่าที่กำหนด ❌ ไม่ต้อง ต้องการกรองด้วย equality แบบง่าย
contains() คืนค่า true/false ว่ามีค่าหรือไม่ ❌ ไม่ต้อง ต้องการตรวจสอบว่ามี item ที่ตรงเงื่อนไขหรือไม่

ตัวอย่างการใช้งาน reject() แบบต่างๆ

Example 1 – ลบ Users ที่ไม่ Active

$users = collect([
    ['name' => 'John', 'is_active' => true],
    ['name' => 'Jane', 'is_active' => false],
    ['name' => 'Bob', 'is_active' => true],
    ['name' => 'Alice', 'is_active' => false],
]);

// ลบ users ที่ไม่ active ออก เก็บเฉพาะ active
$activeUsers = $users->reject(fn($user) => !$user['is_active']);
// Result: John, Bob

Example 2 – ลบ Admin Users ออกจากรายการ

$users = collect([
    ['id' => 1, 'name' => 'John', 'role' => 'user'],
    ['id' => 2, 'name' => 'Jane', 'role' => 'admin'],
    ['id' => 3, 'name' => 'Bob', 'role' => 'user'],
    ['id' => 4, 'name' => 'Alice', 'role' => 'admin'],
]);

$nonAdmins = $users->reject(fn($user) => $user['role'] === 'admin');
// Result: John, Bob (users ที่ไม่ใช่ admin)

Example 3 – กรองสินค้าตามราคา (ลบราคาสูงเกินไป)

$products = collect([
    ['name' => 'Product A', 'price' => 100],
    ['name' => 'Product B', 'price' => 250],
    ['name' => 'Product C', 'price' => 500],
    ['name' => 'Product D', 'price' => 50],
]);

// ลบสินค้าราคาเกิน 200 ออก
$affordable = $products->reject(fn($product) => $product['price'] > 200);
// Result: Product A (100), Product D (50)

Example 4 – ลบรายการว่างเปล่าออกจาก Collection

$collection = collect([
    ['name' => 'John', 'email' => '[email protected]'],
    ['name' => 'Jane', 'email' => ''],
    ['name' => 'Bob', 'email' => '[email protected]'],
    ['name' => 'Alice', 'email' => null],
]);

// ลบ users ที่ไม่มี email
$validUsers = $collection->reject(fn($user) => empty($user['email']));
// Result: John, Bob

Example 5 – ลบ Emails ที่ไม่ถูกต้อง

$emails = collect([
    '[email protected]',
    'invalid-email',
    '[email protected]',
    'not-an-email',
    '[email protected]',
]);

// ลบ email ที่ไม่ถูกต้อง
$validEmails = $emails->reject(fn($email) => !filter_var($email, FILTER_VALIDATE_EMAIL));
// Result: [email protected], [email protected], [email protected]

Example 6 – ลบ Orders ที่ถูกยกเลิกและมียอดต่ำ

$orders = collect([
    ['id' => 1, 'status' => 'completed', 'total' => 100],
    ['id' => 2, 'status' => 'cancelled', 'total' => 200],
    ['id' => 3, 'status' => 'cancelled', 'total' => 30],
    ['id' => 4, 'status' => 'completed', 'total' => 150],
]);

// ลบ orders ที่ถูกยกเลิกและมียอดต่ำกว่า 50
$validOrders = $orders->reject(fn($order) => 
    $order['status'] === 'cancelled' && $order['total'] < 50
);
// Result: id 1, 2, 4 (ลบ id 3 ออก)

Example 7 – กรองด้วย Eloquent Collection

// ดึง articles และลบที่ไม่มี excerpt
$articles = Article::all()->reject(fn($article) => empty($article->excerpt));

// ลบ users ที่ไม่ active แล้ว map เป็น name
$activeUserNames = User::all()
    ->reject(fn($user) => !$user->is_active)
    ->map(fn($user) => $user->name);

Example 8 – Higher-Order Message (Laravel 8+)

สำหรับ callbacks ที่เรียก method เดียว:

$users = collect([
    new User(['name' => 'John', 'is_active' => true]),
    new User(['name' => 'Jane', 'is_active' => false]),
]);

// ใช้ higher-order message
$inactiveUsers = $users->reject->isActive();
// Result: Jane (ถูก reject ออกเพราะ isActive() return true)

Real-world Use Cases – การใช้งานจริงในโปรเจกต์

reject() real-world use cases in dark terminal style

ลบ Cart Items ที่สินค้าหมดสต็อก

$cartItems = collect([
    ['product_id' => 1, 'name' => 'Shirt', 'in_stock' => true],
    ['product_id' => 2, 'name' => 'Pants', 'in_stock' => false],
    ['product_id' => 3, 'name' => 'Shoes', 'in_stock' => true],
]);

$availableItems = $cartItems->reject(fn($item) => !$item['in_stock']);

กรอง Notifications ที่ยังไม่อ่าน

$notifications = collect([
    ['id' => 1, 'message' => 'New order', 'read' => true],
    ['id' => 2, 'message' => 'Payment received', 'read' => false],
    ['id' => 3, 'message' => 'Shipping update', 'read' => false],
]);

$unreadNotifications = $notifications->reject(fn($n) => $n['read']);

ลบ Categories ที่ไม่มี Products

$categories = Category::with('products')->get();

$categoriesWithProducts = $categories->reject(fn($category) => 
    $category->products->isEmpty()
);

ทำความสะอาด API Response

$apiData = SomeAPI::get();

// ลบ null values และ empty strings
$cleanData = collect($apiData)->reject(fn($value) => 
    $value === null || $value === ''
);

Chaining กับ Methods อื่นๆ

$result = collect($data)
    ->reject(fn($item) => $item['status'] === 'archived')  // ลบ archived ออก
    ->reject(fn($item) => $item['views'] < 100)            // ลบ views ต่ำออก
    ->map(fn($item) => $item['title'])                     // เอาเฉพาะ title
    ->unique()                                             // เอาซ้ำออก
    ->values();                                            // reset keys

Common Mistakes – ข้อผิดพลาดที่พบบ่อย

❌ Mistake 1: สับสนระหว่าง reject กับ filter

// ❌ ผิด - ได้ผลลัพธ์ตรงข้ามกับที่ต้องการ!
$activeUsers = $users->reject(fn($user) => $user->is_active);

// ✅ ถูกต้อง - filter เก็บ active, reject ลบ active
$activeUsers = $users->filter(fn($user) => $user->is_active);
// หรือ
$inactiveUsers = $users->reject(fn($user) => $user->is_active);

❌ Mistake 2: ลืมว่า callback ต้อง return true เพื่อลบ

$collection = collect([1, 2, 3, 4, 5]);

// ❌ ผิด - คิดว่า return false จะลบ... แต่ไม่ใช่!
$wrong = $collection->reject(fn($n) => $n < 3); // ลบ 1, 2 ออก เก็บ 3, 4, 5

// ✅ ถูกต้อง - callback return true = ลบออก
$right = $collection->reject(fn($n) => $n > 3); // เก็บ 1, 2, 3 ลบ 4, 5

❌ Mistake 3: ปนกับ map (filter vs transform)

$collection = collect([1, 2, 3, 4]);

// ❌ ผิด - reject ไม่ใช่ transform
$wrong = $collection->reject(fn($n) => $n * 2); // ไม่ทำงานอย่างที่คิด

// ✅ ถูกต้อง - reject สำหรับ filter, map สำหรับ transform
$filtered = $collection->reject(fn($n) => $n % 2 === 0); // [1, 3]
$mapped = $collection->map(fn($n) => $n * 2);             // [2, 4, 6, 8]

❌ Mistake 4: ลืมว่า return new collection (immutable)

$original = collect([1, 2, 3, 4, 5]);

// ❌ ผิด - $original ไม่เปลี่ยน
$result = $original->reject(fn($n) => $n % 2 === 0);
echo $original->all(); // [1, 2, 3, 4, 5] - ยังเหมือนเดิม!

// ✅ ถูกต้อง - ใช้ result ที่ได้จาก reject
$result = $original->reject(fn($n) => $n % 2 === 0);
echo $result->all(); // [1, 3, 5]

❌ Mistake 5: ใช้ reject กับ empty check ใน array ซ้อนกัน

$collection = collect([
    ['name' => 'John', 'tags' => []],
    ['name' => 'Jane', 'tags' => ['php', 'laravel']],
]);

// ❌ ผิด - empty([]) เป็น true ดังนั้นจะลบ John ออก... แต่ถ้าต้องการลบที่มี tags?
$wrong = $collection->reject(fn($item) => empty($item['tags']));

// ✅ ถูกต้อง - ใช้ where หรือ filter แทนจะชัดเจนกว่า
$withTags = $collection->filter(fn($item) => !empty($item['tags']));

Tips & Best Practices

1. เลือกใช้ตามความอ่านง่าย

// อ่านได้ชัดเจนกว่า - "ลบ admin ออก"
$nonAdmins = $users->reject(fn($u) => $u->isAdmin());

// เทียบเท่ากับ - แต่อ่านแล้วต้องคิด "เก็บ users ที่ไม่ใช่ admin"
$nonAdmins = $users->filter(fn($u) => !$u->isAdmin());

2. ใช้กับ Eloquent Collections

// ดึงจาก database แล้วกรองต่อใน memory
$recentArticles = Article::where('published', true)
    ->get()
    ->reject(fn($article) => $article->created_at < now()->subYear())
    ->sortByDesc('views')
    ->take(10);

3. Higher-Order Messages สำหรับ simple cases

// แทนที่จะเขียน
$validUsers = $users->reject(fn($u) => is_null($u->email));

// ใช้ higher-order message (ถ้า method มีอยู่)
$validUsers = $users->reject->email; // จะ reject users ที่ email เป็น falsy

4. Performance – กรองก่อน sort

// ❌ ไม่ดี - sort ก่อน reject
$slow = $collection->sortBy('price')->reject(fn($p) => $p['price'] > 500);

// ✅ ดี - reject ก่อน sort
$fast = $collection->reject(fn($p) => $p['price'] > 500)->sortBy('price');

5. Chain อย่างเป็นระเบียบ

$finalResult = collect($items)
    ->reject(fn($item) => $item['is_archived'])      // 1. ลบ archived ออก
    ->reject(fn($item) => $item['views'] < 10)        // 2. ลบ views ต่ำออก
    ->reject(fn($item) => empty($item['title']))      // 3. ลบ title ว่างออก
    ->map(fn($item) => $item['title'])                // 4. เอา title
    ->unique()                                        // 5. เอาซ้ำออก
    ->values();                                       // 6. reset keys

Related Methods – Methods ที่เกี่ยวข้อง

filter() – ตัวตรงข้ามของ reject

$collection = collect([1, 2, 3, 4, 5]);

// filter เก็บ items ที่ callback return true
$filtered = $collection->filter(fn($n) => $n > 2);
// Result: [3, 4, 5]

// reject ลบ items ที่ callback return true
$rejected = $collection->reject(fn($n) => $n > 2);
// Result: [1, 2]

where() – กรองด้วย key-value แบบเฉพาะเจาะจง

$users = collect([
    ['name' => 'John', 'role' => 'admin'],
    ['name' => 'Jane', 'role' => 'user'],
]);

// where เก็บเฉพาะ users ที่ role === 'admin'
$admins = $users->where('role', 'admin');
// Result: John

// reject ลบ admin ออก (ได้ผลลัพธ์ตรงข้าม)
$nonAdmins = $users->reject(fn($u) => $u['role'] === 'admin');
// Result: Jane

contains() – ตรวจสอบว่ามีค่าหรือไม่

$blockedIds = collect([1, 5, 10]);

$users = collect([
    ['id' => 1, 'name' => 'John'],
    ['id' => 2, 'name' => 'Jane'],
    ['id' => 3, 'name' => 'Bob'],
]);

// ลบ users ที่ id อยู่ใน blockedIds
$allowedUsers = $users->reject(fn($u) => $blockedIds->contains($u['id']));
// Result: Jane, Bob

whereNotIn() – กรองค่าที่ไม่อยู่ใน list

$collection = collect([
    ['name' => 'John', 'role' => 'admin'],
    ['name' => 'Jane', 'role' => 'user'],
    ['name' => 'Bob', 'role' => 'moderator'],
]);

// เทียบเท่ากับการใช้ reject
$nonAdmins = $collection->whereNotIn('role', ['admin']);
// Result: Jane, Bob

สรุป

reject() method เป็นหนึ่งใน tools ที่มีประโยชน์ใน Laravel Collections ช่วยให้เราสามารถกรองข้อมูลในลักษณะ “ตรงข้าม” กับ filter() ได้อย่างง่ายดาย ไม่ว่าจะเป็น:

  • การลบรายการที่ไม่ต้องการออกด้วย reject()
  • การทำความสะอาดข้อมูลด้วยการลบ falsy values
  • การใช้งานร่วมกับ Eloquent Collections
  • การ chain กับ methods อื่นๆ เพื่อโค้ดที่อ่านง่าย

จุดสำคัญคือจำไว้ว่า callback return true = ลบออก และเลือกใช้ระหว่าง reject() กับ filter() ตามความอ่านง่ายของโค้ด

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ Laravel Collections methods อื่นๆ สามารถติดตามบทความต่อไปได้เลยครับ!


FAQ

Q1: reject() กับ filter() ต่างกันอย่างไร?

A: reject() จะ ลบ items ที่ callback คืนค่า true ออก ส่วน filter() จะ เก็บ items ที่ callback คืนค่า true ไว้ สรุปง่ายๆ คือสอง methods นี้ทำงานตรงข้ามกัน

Q2: reject() แบบไม่มี callback ทำงานอย่างไร?

A: ถ้าไม่ระบุ callback, reject() จะลบค่า “falsy” ออกทั้งหมด ได้แก่ null, false, 0, '' (empty string) และ [] (empty array)

Q3: reject() สามารถใช้กับ Eloquent Collection ได้หรือไม่?

A: ได้แน่นอน! reject() ทำงานกับทั้ง Collection ปกติและ Eloquent Collection เช่น User::all()->reject(...) หรือ Article::where(...)->get()->reject(...)


Tags: Laravel, PHP, Laravel Collections, Tutorial

เกี่ยวกับผู้เขียน

ITTHIPAT

สวัสดีครับผม อิทธิพัทธ์ (เป้) ชอบหาเทคนิคต่างๆที่ทำให้ชีวิต Programmer ง่ายขึ้น ทั้ง Automate, Library ชอบทำ Blog และ Video ถ้ามีเวลานะ!

ขอบคุณทุกคนที่ติดตาม และอ่านบทความของผมครับ ผมหวังว่าความรู้ที่เขียนขึ้นในเว็บไซต์นี้จะช่วยทุกท่านได้ไม่มากก็น้อย 

Scroll to Top