Transparently flatten an array

后端 未结 2 1484
耶瑟儿~
耶瑟儿~ 2020-12-11 04:21

Reading this question Merge and group by several arrays i got the following idea: when working with multilevel arrays, with possibly repeating keys, it would be practical to

2条回答
  •  猫巷女王i
    2020-12-11 04:40

    You can also write a simple traversal function:

    function flatten($node, $fn, $keys = array()) {
        if (! is_array($node)) {
            $fn($node, $keys);
        } else {
            foreach ($node as $k => $v) {
                $new_keys   = $keys;
                $new_keys[] = $k;
                flatten($v, $fn, $new_keys);
            }
        }
    }
    
    $array = array( 
        0 => 'a', 
        1 => array('subA','subB',array(0 => 'subsubA', 1 => 'subsubB', 2 => array(0 => 'deepA', 1 => 'deepB'))), 
        2 => 'b', 
        3 => array('subA','subB','subC'), 
        4 => 'c' 
    );
    // will output: a subA subB subsubA subsubB deepA deepB b subA subB subC c 
    flatten($array, function($v, $k) {
        echo $v . ' ';
    });
    

    If you don't want to call it each time with another function as a parameter, I've also written an adapter that will return an array:

    function flatten_array($node) {
        $acc = array();
        flatten($node, function($node, $keys) use (&$acc) {
            $acc[implode('.', $keys)] = $node;
        });
        return $acc;
    }
    
    // will spit out the same output as that in Yoshi's answer:
    foreach (flatten_array($array) as $k => $v) {
        echo $k .' => ' . $v . "\n";
    }
    

    Notes:

    • array_walk_recursive cannot be used/is not the same thing, as it skips over the keys that hold an array
    • I've written my examples with anonymous functions; if your PHP isn't new enough, you have to name the functions and call them with call_user_func.

提交回复
热议问题