Dynamically accessing multidimensional array value

前端 未结 4 1620
长发绾君心
长发绾君心 2021-01-13 21:50

I\'m trying to find (or create) a function. I have a multidimensional array:

$data_arr = [
    \"a\" => [
        \"aa\" => \"abfoo\",
        \"ab\"          


        
相关标签:
4条回答
  • 2021-01-13 22:11

    Try this

    function flatCall($data_arr, $data_arr_call){
        $current = $data_arr;
        foreach($data_arr_call as $key){
            $current = $current[$key];
        }
    
        return $current;
    }
    

    OP's Explanation:

    The $current variable gets iteratively built up, like so:

    flatCall($data_arr, ['a','ab','abc']);
    
    1st iteration: $current = $data_arr['a'];
    2nd iteration: $current = $data_arr['a']['ab'];
    3rd iteration: $current = $data_arr['a']['ab']['abc'];
    

    You could also do if ( isset($current) ) ... in each iteration to provide an error-check.

    0 讨论(0)
  • 2021-01-13 22:18

    You need a function like this:

    function getValue($data_arr, $data_arr_call) {
        foreach ($data_arr_call as $index) {
            if (isset($data_arr[$index])) {
                $data_arr = $data_arr[$index];
            } else {
                return false;
            }
        }
        return $data_arr;
    }
    

    And use it like this:

    $data_arr = [
        "a" => [
            "ab" => [
                "abc" => "abbfoo",
            ],
        ],
    ];
    $data_arr_call = ["a", "ab", "abc"];
    $value = getValue($data_arr, $data_arr_call);
    if ($value) {
        // do your stuff
    }
    
    0 讨论(0)
  • 2021-01-13 22:27

    You can use this function that avoids the copy of the whole array (using references), is able to return a NULL value (using array_key_exists instead of isset), and that throws an exception when the path doesn't exist:

    function getItem(&$array, $path) {
        $target = &$array;
        foreach($path as $key) {
            if (array_key_exists($key, $target))
                $target = &$target[$key];
            else throw new Exception('Undefined path: ["' . implode('","', $path) . '"]');
        }
        return $target;
    }
    

    demo:

    $data = [
        "a" => [
            "aa" => "abfoo",
            "ab" => [
                "aba" => "abafoo",
                "abb" => NULL,
                "abc" => false
            ]
        ]
    ];
    
    var_dump(getItem($data, ['a', 'ab', 'aba']));
    # string(6) "abafoo"
    var_dump(getItem($data, ['a', 'ab', 'abb']));
    # NULL
    var_dump(getItem($data, ['a', 'ab', 'abc']));
    # bool(false)
    try {
        getItem($data, ['a', 'ab', 'abe']);
    } catch(Exception $e) {
        echo $e->getMessage();
    }
    # Undefined path: ["a","ab","abe"]
    

    Note that this function can be improved, for example you can test if the parameters are arrays.

    0 讨论(0)
  • 2021-01-13 22:28

    Wanted to post an even more elegant solution: array_reduce

        $data_arr = [
            "a" => [
                ...
                "ab" => [
                    ...
                    "abc" => "abcfoo"
                ],
                ...
            ],
            ...
        ];
    
        $result = array_reduce(["a", "ab", "abc"], function($a, $b) {
            return $a[$b];
        }, $data_arr);
    
        // returns "abcfoo"
    

    I've been using Javascript's Array.reduce() a lot lately in updating some legacy code to ES6:

    JS:
    const data_obj = {...};
    let result = ['a','ab','abc'].reduce((a, b) => a[b], data_obj);
    
    0 讨论(0)
提交回复
热议问题