功能编程的替代方案,用于缓冲递归循环输出



我想将关联阵列$a = array("key0" => array("key1" => "val0", "key2" => "val1"), "key3" => "val2")转换为字符串$s = "key0.key1=val0&key0.key2=val1&key3=val2&,所以我目前正在做的是..

function assoc_to_str($var, $acc = array()){
  if(is_array($var)){
    foreach($var as $key => $val){
        assoc_to_str($val, array_merge($acc, array($key)));
    }
  }else{echo join('.',$acc).'='.$var.'&';}
}

function assoc_to_str_buffer($arr){
  ob_start();
  arr_to_str($arr);
  return ob_get_clean();
}

..并致电assoc_to_str_buffer()。现在,这感觉很尴尬,我猜这也不是很有效吗?功能风格有更好的方法吗?

如果输出不是连续的字符串,而是foreach循环的当前返回的数组。

通过array_map()

解决方案
function tree_to_str(array $array, $prefix = '') 
{
    return join('&', array_map(function ($key, $value) use ($prefix) 
    {
        if (is_array($value)) {
            return tree_to_str($value, $prefix.$key.'.');
        } else {
            return $prefix.$key.'='.$value;
        }
    }, array_keys($array), $array));
}

更多"命令"解决方案:

function tree_to_str(array $array, $prefix = '') 
{
    $buffer = [];
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $buffer[] = tree_to_str($value, $prefix.$key.'.');
        } else {
            $buffer[] = $prefix.$key.'='.$value;
        }
    }
    return join('&', $buffer);
}

,尽管可以完成"功能样式"。我建议不要重新发明递归轮,并使用RecursiveIteratorIteratorRecursiveArrayIterator

$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($a),
    RecursiveIteratorIterator::SELF_FIRST
);
$path = [];
$result = [];
foreach ($iterator as $key => $value) {
    $depth = $iterator->getDepth();
    $path[$depth] = $key;
    if (!$iterator->hasChildren()) {
        $result[] = implode('.', array_slice($path, 0, $depth + 1)) . "=$value";
    }
}
$result = implode('&', $result);

这里正在工作演示。

正如您可以在迭代器中看到的,您可以使用一个简单的foreach进行此操作。

另外,在逻辑的函数中进行echo是一种不好的做法。

最新更新