Here is an example array:
$foo = array(
'employer' => array(
'name' => 'Foobar Inc',
'phone' => '555-555-5555'
),
'employee' => array(
'name' => 'John Doe',
'phone' => '555-555-5556',
'address' => array(
'state' => 'California',
'zip' => '90210'
)
),
'modified' => '2009-12-01',
);
And I would like to get a result like this:
$fooCompressed = array(
'employer_name' => 'Foobar Inc',
'employer_phone' => '555-555-5555',
'employee_name' => 'John Doe',
'employee_phone' => '555-555-5556'
'employee_address_state' => 'California',
'employee_address_zip' => '90210',
'modified' => '2009-12-01'
)
How would I go about writing a recursive function to handle this?
Approach I liked more is quite similar to some posted here but not equal. I found it into a duped post: https://stackoverflow.com/a/9546215/4791386 by user "Felix Kling"
His code flattens array keys resulting single dimension array with dot concatenated keys, which implies that numerical arrays will creates his own "key paths". This is very useful, but in large amount of similar items inside array could result a ton of meaningless similar paths.
function flatten($array, $prefix = '') {
$result = array();
foreach($array as $key=>$value) {
if(is_array($value)) {
$result = $result + flatten($value, $prefix . $key . '.');
}
else {
$result[$prefix . $key] = $value;
}
}
return $result;
}
In my case, I also needed a "unique like" path flattening as array key, and a sample of the data I could spec. So I extend his approach adding a numeric key squashing optional parameter. Also added optional parameter separator configuration.
The main purpose is make easy to analyze key structure and path related data. I think this method is useful when intended task is key mapping for further full data operations.
/**
* Convert a multidimensional array into a single dimension array.
* Nested array keys will be concatenated with the $separator string
* Numeric keys can also be flattened in a "unique key" array style with $numeric_squash
* If $numeric_squash is true, numeric array keys are concatenated with $numeric_squash_separator,
* for later detection and processing if necessary. "[*]" by default.
* If $numeric_squash_separator is set to false, the array key is flattened so that the values
* would be displayed as if there were no numeric array.
*
* array $array : Array to be flattened
* string $prefix : String to prepend on flattened keys
* string $separator : String concatenated between nested array keys.
* bool $numeric_squash : Squash numeric array keys
* string $numeric_squash_separator : String replacing numeric keys, none if false
*/
public static function array_flatten($array, $prefix = '', $separator = '.' , $numeric_squash = false , $numeric_squash_separator = '[*]') {
$result = array();
foreach($array as $key => $value) {
if(is_array($value)) {
if($numeric_squash && is_numeric($key))
$n_key = $numeric_squash_separator ? $numeric_squash_separator . $separator: '';
else
$n_key = $key . $separator;
$result = $result + self::array_flatten($value, $prefix . $n_key , $separator , $numeric_squash , $numeric_squash_separator);
}
else {
$result[$prefix . ($numeric_squash && is_numeric($key) ? '' : $key)] = $value;
}
}
return $result;
}
Also say that this function is not performance optimized, iterations can be saved on numeric_squash and also some compare operations I think.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With