duanhuang7591
2018-09-28 00:12
浏览 83
已采纳

PHP 7 - 在回调中迭代填充多级数组

I need to build complex multilevel array in callback only, one atomic update per call.

The reason for it: callback is called many times from iterative parser. Finally it should build deserialized PHP-array of binary format being parsed.

Here is runnable code:

const ACTION_VALUE = 1;
const ACTION_ENTER = 2;
const ACTION_LEAVE = 3;

function callback($action, $value, &$param)
{
   switch ($action) 
   {
    case ACTION_ENTER:
        $param['parent'][] = &$param['current'];
        $param['current'][] = [];

        end($param['current']);                
        $param['current'] = &$param['current'][key($param['current'])];
    break;

    case ACTION_LEAVE:
        unset($param['current']);
        $param['current'] = array_pop($param['parent']);
        end($param['current']);
    break;

    case ACTION_VALUE:
        $param['current'][] = $value;
    break;
   }
}

// prepare container
$arr = [];
$arr['data'] = [];
$arr['current'] = &$arr['data'];
$arr['parent'] = [];

// callback invocations
callback(ACTION_VALUE, 1, $arr);
callback(ACTION_VALUE, 2, $arr);
callback(ACTION_ENTER, 0, $arr);
callback(ACTION_VALUE, 10, $arr);
callback(ACTION_VALUE, 11, $arr);
callback(ACTION_LEAVE, 0, $arr);
callback(ACTION_VALUE, 3, $arr);
callback(ACTION_VALUE, 4, $arr);

// now see result
var_dump(json_encode($arr['data']));

Try it here

Above example prints:

[1,2,[10,11]], but should [1,2,[10,11],3,4].

Update: Multilevel means arbitrary arrays of random depth.

Update: The problem was with array_pop(), see below accepted answer for fixed version.

图片转代码服务由CSDN问答提供 功能建议

我只需要在回调中构建复杂的多级数组,每次调用一次原子更新。

它的原因:从迭代解析器中多次调用回调。 最后,它应该构建正在解析的二进制格式的反序列化PHP数组。

这是可运行的代码:

  const ACTION_VALUE = 1; \  nconst ACTION_ENTER = 2; 
const ACTION_LEAVE = 3; 
 
函数回调($ action,$ value,& $ param)
 {
 switch($ action)
 {
 case ACTION_ENTER:
 $ param  ['parent'] [] =& $ param ['current']; 
 $ param ['current'] [] = []; 
 
 end($ param ['current']);  
 $ param ['current'] =& $ param ['current'] [key($ param ['current'])]; 
 break; 
 
 case ACTION_LEAVE:
 unset($ param [  'current']); 
 $ param ['current'] = array_pop($ param ['parent']); 
 end($ param ['current']); 
 break; 
 
 case ACTION_VALUE  :
 $ param ['current'] [] = $ value; 
 break; 
} 
} 
 
 //准备容器
 $ arr = []; 
 $ arr ['data'  ] = []; 
 $ arr ['current'] =& $ arr ['data']; 
 $ arr ['parent'] = []; 
 
 //回调调用
callback(ACTION_VALUE  ,1,$ arr); 
callback(ACTION_VALUE,2,$ arr); 
callback(ACTION_ENTER,0,$ arr); 
callback(ACTION_VALUE,10,$ arr); 
callback(ACTION_VALUE,11,$ arr)  ; 
callback(ACTION_LEAVE,0,$ arr); 
callback(ACTION_VALUE,3,$ arr); 
callback(ACTION_VALUE,4,$ arr); 
 
 //现在看到结果
var_dump(json_encode($ arr)  ['data'])); 
   
 
 

尝试这里

以上示例pri nts:

[1,2,[10,11]] ,但应该 [1,2,[10,11], 3,4]

更新: 多级意味着随机深度的任意数组。

< strong>更新: 问题出在 array_pop()上,请参见下面接受的固定版本答案。

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 邀请回答

2条回答 默认 最新

  • dongpu1315 2018-09-28 10:49
    最佳回答

    I think the problem is array_pop which doesn't return actual reference to the last element. This one works:

    <?php
    
    const ACTION_VALUE = 1;
    const ACTION_ENTER = 2;
    const ACTION_LEAVE = 3;
    
    function callback($action, $value, &$param)
    {
        switch ($action) {
            case ACTION_ENTER:
                $param['parent'][] = &$param['current'];
                $param['current'][] = [];
    
                end($param['current']);
                $param['current'] = &$param['current'][key($param['current'])];
                break;
    
            case ACTION_LEAVE:
                unset($param['current']);
                end($param['parent']);
                $param['current'] = &$param['parent'][key($param['parent'])];
                unset($param['parent'][key($param['parent'])]);
                end($param['current']);
                break;
    
            case ACTION_VALUE:
                $param['current'][] = $value;
                break;
        }
    }
    
    // prepare container
    $arr = [];
    $arr['data'] = [];
    $arr['current'] = &$arr['data'];
    $arr['parent'] = [];
    
    // callback invocations
    callback(ACTION_VALUE, 1, $arr);
    callback(ACTION_VALUE, 2, $arr);
    callback(ACTION_ENTER, 0, $arr);
    callback(ACTION_VALUE, 10, $arr);
    callback(ACTION_VALUE, 11, $arr);
    callback(ACTION_ENTER, 0, $arr);
    callback(ACTION_VALUE, 40, $arr);
    callback(ACTION_VALUE, 41, $arr);
    callback(ACTION_LEAVE, 0, $arr);
    callback(ACTION_LEAVE, 0, $arr);
    callback(ACTION_VALUE, 3, $arr);
    callback(ACTION_VALUE, 4, $arr);
    
    // now see result
    var_dump(json_encode($arr['data']));
    
    评论
    解决 无用
    打赏 举报
查看更多回答(1条)

相关推荐 更多相似问题