功能编程替代缓冲递归foreach循环输出

时间:2016-12-16 09:58:06

标签: php arrays optimization functional-programming

我想将关联数组$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循环的当前返回数组,那也没关系。

2 个答案:

答案 0 :(得分:1)

虽然,它可以完成"功能风格"。我建议不要重新发明递归轮并使用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);

这是working demo

正如您在迭代器中所看到的,您可以使用一个简单的foreach来完成此任务。

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

答案 1 :(得分:1)

通过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);
}