【问题标题】:Concatenating func_get_args into a multidimentional array将 func_get_args 连接成一个多维数组
【发布时间】:2016-01-01 13:08:05
【问题描述】:

我在另一个网站上遇到了这个问题,在尝试了一个小时后(可能是我周日的大脑)我放弃了。问题是:如果有函数foo

function foo(){}

函数可以调用为(参数可以是>= 2,其中最后一个总是值,前一个是数组的一部分)。

所以调用函数为:

foo('arg1', 'value');

应该导致:

$array['arg1'] = 'value';

如果它有多个参数,则相同:

foo('arg1', 'argx', 'argz', 'value');

应该产生:

$array['arg1']['argx']['argz'] = 'value';

这是我的sad attempt

function foo()
{
    $items = func_get_args();
    $value = array_pop($items);
    $array = array_shift($items);

    // Construct first element
    $array = array($array => array());

    foreach ($items as $el) {
       insert_last($array, $value);
    }

    return $array;
}

function insert_last(&$array, $value)
{
    $copy = $array;
    while (true) {
        $keys = array_keys($copy);
        $last = $copy[$keys[count($copy)-1]];
        var_dump($last);
        if (empty($last)) {
            $last = $value;
            break;
        }
        $copy = $last;
    }
    var_dump($array, $copy);
}

很确定可能有一个我目前想不出的更简单的解决方案。谢谢!

【问题讨论】:

    标签: php arrays recursion multidimensional-array


    【解决方案1】:
    function foo()
    {
        $items = func_get_args();
        $value = array_pop($items);
        $array = [];
        $arrayPtr = &$array;
    
        foreach ($items as $element) {
            $arrayPtr[$element] = null;
            $arrayPtr = &$arrayPtr[$element];
        }
        $arrayPtr[$element] = $value;
    
        return $array;
    }
    
    var_dump(foo('arg1', 'argx', 'argz', 'value'));
    

    Demo

    【讨论】:

    • 好主意!我只需要更新指针以仅在末尾添加值:$arrayPtr[$element] = $value; -> $arrayPtr = $value; 以避免重复最后一个条目。
    【解决方案2】:

    通过使用call_user_func_array()的递归

    <?php
    function foo() {
        $items = func_get_args();
        if ( 1==count($items) ) {
            return array_shift($items);
        }
        else {
            $key = array_shift($items);
            return array( $key=>call_user_func_array('foo', $items) );
        }
    }
    
    var_dump(foo('arg1', 'argx', 'argz', 'value'));
    

    编辑:同样的事情没有 func_get_args() 但使用 variadic function

    <?php
    function foo(...$items) {
        if ( 1==count($items) ) {
            return array_shift($items);
        }
        else {
            $key = array_shift($items);
            return array( $key=>call_user_func_array('foo', $items) );
        }
    }
    
    var_dump(foo('arg1', 'argx', 'argz', 'value'));
    

    【讨论】:

    • 很好,我一直喜欢小任务的递归解决方案,它可以让事情变得更干净!
    • 自从 Mark 打败了我,我不得不想出另一个解决方案 ;-) 但是上次我检查 call_user_func_array 是一个相对昂贵的操作。由于这是一个小函数,因此引用的范围受到限制,我将在这里使用引用而不是递归。
    【解决方案3】:

    类似的东西呢

    function foo()
    {
        $args = func_get_args();
    
        $items = array_pop($args);
        foreach (array_reverse($args) as $item) {
            $items = array($item => $items);
        }
    
        return $items;
    }
    
    var_dump(foo('arg1', 'argx', 'argz', 'value'));
    

    Demo

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多