如何合并二维关联数组中键存在于其他行值中的相关行?
Merge Linked Associative Arrays in PHP
Got it, let's break down how to solve this problem: we need to merge all related entries in an associative array where any key that appears as a value in another entry gets its values rolled up into the parent entry. And we have to handle nested references too—like how 50007 points to 50008, which should also end up in the 44259 entry.
Step 1: Define the Approach
First, we need to:
- Identify all "referenced keys" (keys that appear as values anywhere in the array)
- Find our "root keys" (keys that are not referenced by any other entry—these are the top-level entries we'll keep in the final array)
- For each root key, recursively collect all values from referenced keys, making sure we don't process the same key twice (to avoid infinite loops if there's a circular reference)
Step 2: Implement the Solution
Here's a PHP function that does exactly this:
function mergeLinkedArrays(array $array): array { // First, collect all keys that are referenced as values in the array $referencedKeys = []; foreach ($array as $values) { foreach ($values as $val) { if (is_int($val) && array_key_exists($val, $array)) { $referencedKeys[$val] = true; } } } // Identify root keys (keys not present in referencedKeys) $rootKeys = array_filter(array_keys($array), function($key) use ($referencedKeys) { return !isset($referencedKeys[$key]); }); $merged = []; $processed = []; // Track processed keys to avoid loops and duplicates // Recursive function to collect all linked values $collectValues = function($key) use (&$collectValues, &$array, &$processed) { if (isset($processed[$key])) { return []; } $processed[$key] = true; $values = $array[$key]; foreach ($values as $val) { if (is_int($val) && array_key_exists($val, $array)) { // Merge in values from the referenced key $values = array_merge($values, $collectValues($val)); } } return $values; }; // Build the merged array foreach ($rootKeys as $key) { $processed = []; // Reset processed for each root key $merged[$key] = $collectValues($key); } return $merged; }
Step 3: Test with Your Example
Let's plug in your sample array:
$array = [ 44259 => [50007, 50009, 46372], 50007 => [50008], 50009 => [50010], 66666 => ['no', 'other', 'links'], 46372 => [46418, 46419, 46421], 46421 => [146880] ]; $mergedArray = mergeLinkedArrays($array); print_r($mergedArray);
Output:
Array ( [44259] => Array ( [0] => 50007 [1] => 50009 [2] => 46372 [3] => 50008 [4] => 50010 [5] => 46418 [6] => 46419 [7] => 46421 [8] => 146880 ) [66666] => Array ( [0] => no [1] => other [2] => links ) )
Notes
- Duplicate Values: If your array might have duplicate values across linked entries, you can add
$values = array_unique($values);after thearray_mergestep to clean them up. - Circular References: The
$processedarray ensures we don't loop infinitely if, say,50007had a value pointing back to44259. - Non-Integer Values: The code checks if a value is an integer before checking if it's a key—this handles entries like
66666with string values that don't reference any keys.
内容的提问来源于stack exchange,提问作者Smiley
相关产品推荐
相关产品推荐

