phparraysforeachvariable-assignmentdestructuring

While destructuring an array, can the same element value be accessed more than once?


Since PHP7.1, a foreach() expression can implement array destructuring as a way of unpacking row values and make individualized variable assignments.

When using array destructuring within a foreach() loop, can a specific value be accessed by its associative key more than once?

For example:

$array = [
    ['group' => 'A', 'name' => 'Ann', 'age' => 19],
    ['group' => 'B', 'name' => 'Bea', 'age' => 26],
    ['group' => 'A', 'name' => 'Cam', 'age' => 32],
    ['group' => 'B', 'name' => 'Des', 'age' => 24]
];

I know I can use:

foreach ($array as ['group' => $group, 'name' => $name, 'age' => $age]) {
    // do stuff with $group, $name, and $age
}

But what if I want to access, say, $group a second time while destructuring? Is it possible?


Solution

  • It looks pretty unorthodox and there will be very few scenarios when it is useful, but yes it is possible/valid.

    Just repeat the "key => value" syntax again and provide a different variable in the value position. In this context, the keys may be repeated.

    Here is a demonstration of using array destructuring to "pivot" a result set with a body-less foreach loop.

    Code: (Demo)

    $array = [
        ['group' => 'A', 'name' => 'Ann', 'age' => 19],
        ['group' => 'B', 'name' => 'Bea', 'age' => 26],
        ['group' => 'A', 'name' => 'Cam', 'age' => 32],
        ['group' => 'B', 'name' => 'Des', 'age' => 24]
    ];
    
    $result = [];
    foreach ($array as ['group' => $group, 'group' => $result[$group]['group'], 'name' => $name, 'age' => $result[$group][$name]]);
    # assignment of group value----^^^^^^
    # 1st use of group value--------------------------^^^^^^^^^^^^^^^^^^^^^^^^
    # assignment of name value------------------------------------------------------------^^^^^
    # 2nd use of group value and 1st use of name value----------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^
    
    var_export($result);
    

    Output:

    array (
      'A' => 
      array (
        'group' => 'A',
        'Ann' => 19,
        'Cam' => 32,
      ),
      'B' => 
      array (
        'group' => 'B',
        'Bea' => 26,
        'Des' => 24,
      ),
    )
    

    Key access is not restricted to static values; array keys can be dynamically accessed: (Demo)

    $array = [
        ['group' => 'A', 'A' => 1, 'B' => 2,],
        ['group' => 'B', 'A' => 3, 'B' => 4,],
        ['group' => 'A', 'A' => 5, 'B' => 6,],
        ['group' => 'B', 'A' => 7, 'B' => 8,]
    ];
    $result = [];
    foreach ($array as ['group' => $group, $group => $result[$group][]]);
    var_export($result);
    

    Output:

    array (
      'A' => 
      array (
        0 => 1,
        1 => 5,
      ),
      'B' => 
      array (
        0 => 4,
        1 => 8,
      ),
    )
    

    The same technique works outside of the context of a foreach() loop as well. (Demo)

    ['one' => $result[], 'one' => $result[]] = ['one' => 1];
    var_export($result);
    

    Output:

    array (
      0 => 1,
      1 => 1,
    )