array_filter($array, $callback) trả về các phần tử của $array mà $callback trả về true (hoặc bất kỳ giá trị nào chuyển được thành true). Mảng đứng trước, callback đứng sau, và các phần tử được giữ lại vẫn giữ khóa ban đầu.
Khóa trong kết quả là 1, 3, 5, 7: vị trí của các giá trị đó trong mảng gốc. Chi tiết này quan trọng hơn vẻ ngoài của nó, và mục đánh số lại bằng array_values bên dưới sẽ chỉ cách xử lý.
Xóa giá trị rỗng khỏi mảng
Gọi array_filter mà không có callback, hàm sẽ xóa mọi giá trị chuyển thành false: chuỗi rỗng, null, false, 0, "0" và mảng rỗng. Đây là cách nhanh nhất để dọn dẹp các mảnh do explode() tạo ra hoặc một danh sách trường biểu mẫu.
Kết quả đầu tiên còn mất cả "0" và 0, trong khi đây thường là dữ liệu thật (số lượng bằng 0, một chữ số trong mã bưu chính). Khi 0 là câu trả lời hợp lệ, hãy tự viết callback như ở lần gọi thứ hai. Trang empty có danh sách đầy đủ các giá trị mà PHP coi là rỗng.
Đánh số lại kết quả bằng array_values
Vì khóa được giữ nguyên, một list sau khi lọc có thể bị khuyết. Khi đó vòng lặp for bắt đầu từ 0 sẽ gặp những khóa không tồn tại, và json_encode biến kết quả thành object JSON thay vì mảng. array_values() sẽ đánh số lại.
Lọc theo khóa với ARRAY_FILTER_USE_KEY
Đối số thứ ba chọn thứ mà callback nhận được. ARRAY_FILTER_USE_KEY chỉ truyền khóa. ARRAY_FILTER_USE_BOTH truyền giá trị rồi đến khóa.
Để giữ một tập khóa cố định mà bạn đã biết trước, array_intersect_key($config, array_flip(['db_host', 'db_port'])) làm được việc tương tự mà không cần callback.
Lọc mảng đa chiều
Phần lớn dữ liệu thực tế là một danh sách các hàng. Callback nhận từng hàng một, nên bạn kiểm tra trường nào cũng được.
Đổi $maxPrice rồi chạy lại. Sau đó, nếu chỉ cần lấy tên, hãy truyền kết quả cho array_column: array_column($affordable, 'name').
Lọc, rồi map, rồi reduce
array_filter chọn phần tử, array_map biến đổi chúng, còn array_reduce gộp cả mảng thành một giá trị. array_reduce($array, $callback, $initial) gọi callback với tổng đang cộng dồn và phần tử tiếp theo.
Với một phép cộng đơn giản, array_sum($totals) ngắn gọn hơn. array_reduce phát huy tác dụng khi kết quả là thứ khác: một chuỗi, số lượng theo từng nhóm, hay hàng lớn nhất.
Lỗi thường gặp: thay đổi giá trị bên trong array_filter
Giá trị trả về của callback chỉ quyết định một phần tử có được giữ lại hay không. Mọi thứ khác mà nó tính toán đều bị bỏ đi, nên đoạn code này không trim được gì cả:
Hãy biến đổi bằng array_map, rồi mới lọc, và thêm array_values khi bạn cần một list gọn gàng.
Câu hỏi thường gặp
Làm sao xóa giá trị rỗng khỏi mảng trong PHP?
Gọi array_filter($array) mà không truyền callback: hàm sẽ bỏ mọi giá trị falsy ("", null, false, 0, "0", []). Để chỉ bỏ chuỗi rỗng và null nhưng vẫn giữ 0, hãy truyền callback: array_filter($array, fn($v) => $v !== '' && $v !== null).
Vì sao array_filter giữ lại các khóa cũ?
array_filter không bao giờ đánh số lại: các phần tử được giữ vẫn nằm ở khóa ban đầu, nên một list có thể trả về dạng [0 => 'a', 2 => 'c']. Bọc nó trong array_values() để có lại 0, 1, 2, việc này cũng giúp json_encode tạo ra mảng JSON thay vì object.
Làm sao lọc mảng theo khóa trong PHP?
Truyền ARRAY_FILTER_USE_KEY làm đối số thứ ba, khi đó callback nhận khóa thay vì giá trị: array_filter($arr, fn($k) => str_starts_with($k, 'db_'), ARRAY_FILTER_USE_KEY). Dùng ARRAY_FILTER_USE_BOTH để nhận cả giá trị lẫn khóa.
array_filter và array_map khác nhau thế nào?
array_filter quyết định phần tử nào được giữ lại và trả về chúng nguyên vẹn. array_map thay đổi từng phần tử và trả về đúng số phần tử như ban đầu. Muốn làm cả hai, hãy nối chúng lại: array_map('strtoupper', array_filter($arr)).