PHP多维数组按指定键值筛选返回主数组的实现方案
Hey there! Let's tackle your two PHP array filtering problems one by one — I've run into similar recursive snags before, so I know exactly where you might be tripping up.
Problem 1: Filter Program Arrays with "New Jersey" Campuses
First, let's assume your $programs array looks something like this (I'm using a realistic example to make this concrete):
$programs = [ [ 'id' => 1, 'name' => 'Computer Science', 'campuses' => [ ['campus_title_override' => 'New Jersey - Newark'], ['campus_title_override' => 'New York - Manhattan'] ] ], [ 'id' => 2, 'name' => 'Mechanical Engineering', 'campuses' => [ ['campus_title_override' => 'California - LA'] ] ], [ 'id' => 3, 'name' => 'Business Administration', 'campuses' => [ ['campus_title_override' => 'New Jersey - Princeton'], ['campus_title_override' => 'Pennsylvania - Philly'] ] ] ];
Your recursive function returning empty is almost certainly due to missing checks for nested array existence or not properly triggering a match when the term is found. Here are two solid solutions:
Option 1: Iterative Filter (Great for Debugging)
This is straightforward and easier to trace if you're still troubleshooting:
function filterProgramsByCampus($programs, $searchTerm) { $filteredPrograms = []; foreach ($programs as $program) { // Loop through each campus in the current program foreach ($program['campuses'] as $campus) { // Check if the campus title contains your search term if (str_contains($campus['campus_title_override'], $searchTerm)) { $filteredPrograms[] = $program; break; // Stop checking this program's campuses once we find a match } } } return $filteredPrograms; } // Usage example $matchingPrograms = filterProgramsByCampus($programs, 'New Jersey'); print_r($matchingPrograms); // Returns programs 1 and 3
Option 2: Recursive Filter (For Deeply Nested Campuses)
If your campuses array might have deeper nested sub-campuses, recursion is the way to go. The key here is adding checks to avoid errors from missing fields:
// Helper function to check if any campus (or sub-campus) matches function hasMatchingCampus($campuses, $searchTerm) { foreach ($campuses as $campus) { // First check if the current campus has the target field and matches if (isset($campus['campus_title_override']) && str_contains($campus['campus_title_override'], $searchTerm)) { return true; } // If there are nested campuses, recurse into them if (isset($campus['campuses']) && is_array($campus['campuses'])) { if (hasMatchingCampus($campus['campuses'], $searchTerm)) { return true; } } } return false; } // Main function to filter programs function filterProgramsRecursive($programs, $searchTerm) { return array_filter($programs, function($program) use ($searchTerm) { return hasMatchingCampus($program['campuses'], $searchTerm); }); } // Usage example $matchingPrograms = filterProgramsRecursive($programs, 'New Jersey'); print_r($matchingPrograms);
Problem 2: Filter Campus Arrays with Matching Programs
This is a mirror of the first problem — we just flip the hierarchy. Let's assume your $campuses array looks like this:
$campuses = [ [ 'id' => 1, 'campus_name' => 'New Jersey - Newark', 'programs' => [ ['program_name' => 'Computer Science'], ['program_name' => 'Mathematics'] ] ], [ 'id' => 2, 'campus_name' => 'California - LA', 'programs' => [ ['program_name' => 'Mechanical Engineering'] ] ], [ 'id' => 3, 'campus_name' => 'New Jersey - Princeton', 'programs' => [ ['program_name' => 'Business Administration'], ['program_name' => 'Computer Science'] ] ] ];
Iterative Filter (Simple & Direct)
function filterCampusesByProgram($campuses, $searchTerm) { $filteredCampuses = []; foreach ($campuses as $campus) { foreach ($campus['programs'] as $program) { // Swap out 'program_name' for your actual program field to match if (str_contains($program['program_name'], $searchTerm)) { $filteredCampuses[] = $campus; break; } } } return $filteredCampuses; } // Usage example: Filter campuses with "Computer Science" programs $matchingCampuses = filterCampusesByProgram($campuses, 'Computer Science'); print_r($matchingCampuses); // Returns campuses 1 and 3
Recursive Filter (For Deeply Nested Programs)
If your programs have nested sub-programs, use this recursive approach:
function hasMatchingProgram($programs, $searchTerm) { foreach ($programs as $program) { if (isset($program['program_name']) && str_contains($program['program_name'], $searchTerm)) { return true; } if (isset($program['programs']) && is_array($program['programs'])) { if (hasMatchingProgram($program['programs'], $searchTerm)) { return true; } } } return false; } function filterCampusesRecursive($campuses, $searchTerm) { return array_filter($campuses, function($campus) use ($searchTerm) { return hasMatchingProgram($campus['programs'], $searchTerm); }); } // Usage example $matchingCampuses = filterCampusesRecursive($campuses, 'Computer Science'); print_r($matchingCampuses);
Quick Notes:
- If you're on PHP < 8.0, replace
str_contains($haystack, $needle)withstrpos($haystack, $needle) !== false(sincestr_containswas added in 8.0). - Always use
isset()checks for array fields — missing fields will cause errors that can make your functions return empty unexpectedly (this is probably why your original recursive function failed!). - Swap out the field names (like
program_name) for whatever actual fields you need to match in your real array.
内容的提问来源于stack exchange,提问作者unixmiah

