【问题标题】:How to 'merge' some array elements into a element of the same array?如何将一些数组元素“合并”到同一个数组的元素中?
【发布时间】:2010-09-30 15:39:41
【问题描述】:
$foo = array(
    '1' => '2',
    '3' => array(
        '4' => '5'
    ),
    '6' => array(
        '7' => '8',
        '9' => '10',
        '11' => array(
            '12' => '13',
            '14' => '15'
        )
    )
);

$bar = array(
    '1',
    '6' => array(
        '7',
        '11' => array(
            '12'
        )
    )
);

Foo 是一个我必须编辑的数组,Bar 是我需要做的编辑。

我必须在 Foo 数组中创建另一个元素,其中包含 Bar 中指向的元素,并从 Foo 中删除原始元素。

所以,有了数组,最终的数组应该是:

Array(
    '3' => array(
        '4' => '5'
    ),
    '6' => array(
        '9' => '10',
        '11' => array(
            '14' => '15'
        )
    ),
    'merged' => array(
        '1' => '2',
        '6' => array(
            '7' => '8',
            '11' => array(
                '12' => '13'
            )
        )
    )
)

我已经构建了这个递归函数,但仅适用于数组的第一级:

foreach($bar AS $key => $value){
    if(is_array($value)){
        s($foo, $key, $value);
    }else{
        $foo['merged'][$value] = $foo[$value];
        unset($foo[$value]);
    }
}


function s(&$form, $key, $value){
    if(is_array($value)){
        foreach($value AS $k => $v){
            s($form, $k, $v);
        }
    }else{
        $form['merged'][$value] = $form[$value];
        unset($foo[$value]);
    }
}

有什么想法吗?

【问题讨论】:

    标签: php arrays recursion multidimensional-array


    【解决方案1】:

    目前你的脚本最大的问题是你假设一个没有键的元素是一个独立的结构。数组 $bar 实际上 在 PHP 中看起来像这样:

    $bar = array(
        '0' => '1',
        '6' => array(
            '0' => '7',
            '11' => array(
                '0' => '12'
            )
        )
    )
    

    意识到这一点,当您在 $bar 中看到键“0”时,很明显我们应该查看值并将该键=>值对移动到 $foo['merged'],但是当您看到时它变得更加复杂'6'。当您意识到不能只嵌套 foreach() 循环时,情况会更加复杂,因为该数组可能存在无限级别。

    在任何抽象数据类型中处理任意数量的级别的技巧是带有静态计数器的递归函数(用于跟踪级别)。这样我们就可以继续深入$bar,但是当我们完成时我们会回到我们遗漏的地方。如果我们将计数器设为数组,我们可以跟踪我们是如何到达我们所在的位置的。这样我们以后可以在 $foo 中找到该元素。

    /* recursive_foobar is the only function you call */
    
    function recursive_foobar(&$foo, $bar, &$merged){
        static $counter;
        if(is_empty($counter)){ // initialize counter the first time
            $counter = array();
        }
        foreach($bar as $key => $element){
            if(is_array($element)){
                $counter[] = $key;
                recursive_foobar($foo, $element, $merged[$key]);
            } else {
                $old_value = recursive_get($foo, array_push($counter, $element));
                recursive_remove($foo, array_push($counter, $element));
                array_merge($merged, $old_value);
            }
        }
        return $merged;
    }
    
    /* recursive_get returns a multi-level array containing the requested element at the lowest level */
    
    function recursive_get($haystack, $key){
        static $return;
        if(count($key) > 1){
            $return[] = array(recursive_get($haystack[$key[0]], array_shift($key)));
        } else {
            $return[] = $haystack[$key[0]];
        }
        return $return;
    }
    
    /* recursive_remove will remove the requested element, leaving all containers untouched */
    
    function recursive_remove(&$array, $key){
        if(count($key) > 1){
            recursive_remove($array[$key[0]], array_shift($key));
        } else {
            remove($array[$key[0]]) ???
        }
    }
    
    $foo['merged'] = array();
    recursive_foobar($foo, $bar, $foo['merged']);
    

    这有点草率,但您的要求涉及一些相当高级的构造和一些复杂的逻辑。可能有一些我没有记住的 PHP 函数可以减少一些代码,但你说的是从任意长度、任意深度和任意次数的数组中删除任意元素......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-18
      • 2019-12-05
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多