php - recorrer - matrices en r studio
PHP convierte una matriz anidada a una sola matriz mientras concatena las teclas? (5)
Aquí hay una matriz de ejemplo:
$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'',
);
Y me gustaría obtener un resultado como este:
$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''
)
¿Cómo podría escribir una función recursiva para manejar esto?
Algo como esto:
function makeNonNestedRecursive(array &$out, $key, array $in){
foreach($in as $k=>$v){
if(is_array($v)){
makeNonNestedRecursive($out, $key . $k . ''_'', $v);
}else{
$out[$key . $k] = $v;
}
}
}
function makeNonNested(array $in){
$out = array();
makeNonNestedRecursive($out, '''', $in);
return $out;
}
// Example
$fooCompressed = makeNonNested($foo);
Aquí hay una función que le permite especificar un prefijo de nivel superior a través del segundo parámetro:
function flatten_array($array, $prefix = null) {
if ($prefix) $prefix .= ''_'';
$items = array();
foreach ($array as $key => $value) {
if (is_array($value))
$items = array_merge($items, flatten_array($value, $prefix . $key));
else
$items[$prefix . $key] = $value;
}
return $items;
}
/**
* Flatten a multi-dimensional array or a nested object, constructing concatenated keys for
* nested elements.
* @param array or object $array - the array or object to be flattened
* @param array or string $key_path - current parent keys path.
* Pass this parameter as string if you need to set a common prefix for all keys
* @param string $level_separator - keys concatenation glue
* @param array $flat - resulting flattened array (omit this parameter when calling the function)
* @return single-dimensional array with all array keys as concatenated keys of elements''
* paths through the data structure
*/
function flattenArray($array, &$key_path = array(), $level_separator = ''.'', &$flat = array())
{
if(!is_array($key_path))
{
// sanitize key_path
$key_path = array((string)$key_path);
}
foreach($array as $key => $value)
{
// push current key to path
array_push($key_path, $key);
if(is_array($value) || is_object($value))
{
// next level recursion
$flat = array_merge($flat, flattenArray($value, $key_path, $level_separator, $flat));
}
else
{
// write the value directly
$flat[implode($level_separator, $key_path)] = $value;
}
// remove used key
array_pop($key_path);
}
return $flat;
}
Después de algunas iteraciones, he podido refinar una solución a este problema que utiliza un enfoque basado en la pila para evitar la recursión, simplificando un poco las cosas.
/***
* @name array_flatten
* @author Tom Penzer @tpenzer
* Flattens a multi-tiered array into a single-tiered
* associative array with keys reflective of their
* values'' hierarchy.
*
* @param array $array Required - the multi-
* level keyed array to be flattened
* @param string $separator Optional - the string
* used to separate the keys from different levels of
* the hierarchy
*
* @return array a single-level keyed array
***/
function array_flatten($array, $separator = ''_'') {
$output = array();
while (list($key, $value) = each($array)) {
if (is_array($value)) {
$build = array();
foreach ($value as $s_key => $s_value) {
$build[$key . $separator . $s_key] = $s_value;
}
unset($array[$key]);
$array = $build + $array;
unset($build);
continue;//skip write to $output
}
$output[$key] = $value;
unset($array[$key]);
}
return $output;
}
No es exactamente el método solicitado, pero es un buen contraste con los enfoques recursivos del problema.
Creo que este ''truco'' de uso es http_build_query, es menos desagradable que recurrencia (o al menos dejar que php lo haga por usted)
3 líneas de código si su str_replace usa los valores codificados en url para [y]
$string = http_build_query($array);
$string = urldecode($string);
$string = str_replace(
array(''['','']''),
array(''_'','''') ,
$string
);
parse_str($string, $flat_array);
$ flat_array se convierte en:
array(7) {
["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"
}