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

1

5

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?

Knowhow answered 9/4, 2022 at 12:16 Comment(0)
K
6

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,
)
Knowhow answered 9/4, 2022 at 12:16 Comment(6)
Interesting. Very useful for obfuscating code (especially the last one), but anywhere else?Flophouse
This is a very, very fresh discovery for me. I haven't had much time to consider possible scenarios where this "feature" is noticeably beneficial.Knowhow
I'll be interested to hear if you come up with something...Flophouse
(I guess this is where I ask you to "follow" this page.) The second snippet might be used like a array_multi_push() if you wanted to add an element to two different arrays at the same time. ...I guess.Knowhow
Well, I've followed. We'll see what comes up...Flophouse
I'm hanging for PSR guidelines to tell me how to multi-line the destructured foreach(). It seems yet to be described.Knowhow

© 2022 - 2024 — McMap. All rights reserved.