PHP合并含results的JSON数组去重失败,求有效解决方法
Hey there! Let's break down exactly what's going wrong with your current code and walk through a reliable solution to merge your three JSON arrays and remove duplicates properly.
What's Wrong with Your Current Approach
Let's unpack the issues in your code step by step:
- Extra brackets & missing "results" field: When you use
array_merge_recursive($array1, $array2, $array3), since all three input arrays have aresultskey, the function merges the values of those keys into a single nested array. Then when you runarray_values(array_unique(...))on the entire merged array (which only has oneresultsentry), you end up wrapping the entire list in an extra set of brackets—and lose the originalresultskey in the process. - Duplicates not being removed:
array_unique($array, SORT_REGULAR)compares entire array elements as-is. In your data, somecat_idvalues are integers (e.g.,4in Array1) while others are strings (e.g.,"5"in Array2). These are treated as distinct values by PHP, so duplicates aren't caught. Even if types matched,array_uniqueisn't the most reliable way to deduplicate objects/arrays based on a unique identifier likecat_id.
Step-by-Step Solution
Here's a straightforward, robust way to merge your arrays and deduplicate them based on cat_id (while fixing type inconsistencies):
1. First, decode your JSON strings (if you haven't already)
// Your original JSON data $json1 = '{"results":[{"cat_id":2,"cat_name":"veterinarian"},{"cat_id":3,"cat_name":"electrician"}, {"cat_id":4,"cat_name":"dentist"}]}'; $json2 = '{"results":[{"cat_id":"8","cat_name":"dental hygienist"},{"cat_id":"5","cat_name":"stocktaker"}, {"cat_id":"9","cat_name":"builder"}]}'; $json3 = '{"results":[{"cat_id":4,"cat_name":"dentist"},{"cat_id":5,"cat_name":"stocktaker"}, {"cat_id":3,"cat_name":"electrician"}]}'; // Decode JSON into associative arrays $array1 = json_decode($json1, true); $array2 = json_decode($json2, true); $array3 = json_decode($json3, true);
2. Merge all the results items into a single list
Instead of merging the top-level arrays, extract and combine just the results contents:
$allCategories = array_merge($array1['results'], $array2['results'], $array3['results']);
3. Deduplicate using cat_id (with type normalization)
We'll use cat_id as a unique key in a temporary array to eliminate duplicates. First, normalize cat_id to a consistent type (string or integer) to avoid mismatches between numeric strings and integers:
$uniqueCategories = []; foreach ($allCategories as $category) { // Convert cat_id to string to handle both integer and string values consistently $normalizedId = (string)$category['cat_id']; // Only keep the first occurrence of each category (remove the if to keep the last occurrence) if (!isset($uniqueCategories[$normalizedId])) { $uniqueCategories[$normalizedId] = $category; } } // Convert the associative array back to an indexed array $uniqueCategories = array_values($uniqueCategories);
4. Wrap back into the original results structure and output
// Reconstruct the JSON structure with the unique categories $finalResult = ['results' => $uniqueCategories]; // Output the final JSON echo json_encode($finalResult);
Alternative: Using array_reduce for Conciseness
If you prefer a more functional approach, you can use array_reduce instead of the foreach loop:
$uniqueCategories = array_reduce($allCategories, function($carry, $category) { $normalizedId = (string)$category['cat_id']; $carry[$normalizedId] = $category; return $carry; }, []); $uniqueCategories = array_values($uniqueCategories); $finalResult = ['results' => $uniqueCategories]; echo json_encode($finalResult);
Expected Output
Running this code will give you the clean, deduplicated JSON you want:
{"results":[{"cat_id":2,"cat_name":"veterinarian"},{"cat_id":3,"cat_name":"electrician"},{"cat_id":4,"cat_name":"dentist"},{"cat_id":"8","cat_name":"dental hygienist"},{"cat_id":"5","cat_name":"stocktaker"},{"cat_id":"9","cat_name":"builder"}]}
内容的提问来源于stack exchange,提问作者CHarris

