求实现按路径删除多维数组元素的unsetElement函数
Got it, let's tackle this problem head-on. You need a function that takes a multidimensional array and a dot-separated path string (like globals.connects.setting1) to remove the target element, while returning a new modified array instead of messing with the original one. Perfect—here's a clean, recursive approach that handles any depth of path and array structure:
The unsetElement Function
function unsetElement(string $path, array $array): array { // Split the path into individual keys $keys = explode('.', $path); $currentKey = array_shift($keys); // If this is the last key in the path, remove it from a copy of the array if (empty($keys)) { $newArray = $array; unset($newArray[$currentKey]); return $newArray; } // If the current key doesn't exist, return the original array (no changes) if (!isset($array[$currentKey]) || !is_array($array[$currentKey])) { return $array; } // Recursively process the nested array, then merge back into a new array copy $newArray = $array; $newArray[$currentKey] = unsetElement(implode('.', $keys), $array[$currentKey]); // Optional: Remove empty nested arrays after element deletion // if (empty($newArray[$currentKey])) { // unset($newArray[$currentKey]); // } return $newArray; }
How It Works
Let’s break down the logic step by step:
- Split the Path: First, we turn the dot-separated string (like
globals.connects.setting1) into an array of keys:['globals', 'connects', 'setting1']. - Base Case: When we reach the final key in the path, we create a copy of the current array, unset the key, and return that copy.
- Recursive Case: For nested keys, we check if the current key exists and points to another array. If so, we recursively call the function on that nested array, then assign the modified nested array back to a copy of the original array.
- Edge Handling: If the path doesn’t exist (e.g., a key is missing or points to a non-array value), the function just returns the original array—no errors, no unexpected changes.
Example Usage
Let’s test it with a sample array:
$originalArray = [ 'globals' => [ 'connects' => [ 'setting1' => 'foo', 'setting2' => 'bar' ], 'theme' => 'dark' ] ]; // Remove the element at 'globals.connects.setting1' $modifiedArray = unsetElement('globals.connects.setting1', $originalArray); print_r($modifiedArray);
Output:
Array ( [globals] => Array ( [connects] => Array ( [setting2] => bar ) [theme] => dark ) )
Optional: Clean Up Empty Nested Arrays
If you want the function to automatically remove empty nested arrays after deleting their last element, uncomment the optional block in the function. For example, if you deleted globals.connects.setting2 instead, the connects array would become empty and get removed from the result.
内容的提问来源于stack exchange,提问作者Ingo

