phparraysmultidimensional-arrayfunctional-programmingarray-flip

Create flat, associative array from 2nd level values and 1st level keys of a 2d array


I'm looking for a way to replace nested foreach loops with a functional programming approach. Here is the sample data:

$mode[1] = [1, 2, 5, 6];
$mode[0] = [3, 4, 7, 8];

Currently my code is this:

foreach ($mode as $key => $value):
  foreach ($value as $v):
    $modes[$v] = $key;
  endforeach;
endforeach;

echo '<pre>' . print_r($modes, 1) . '</pre>';

This generates the desired output (which can be thought of as flipping a 2d array):

array (
  1 => 1,
  2 => 1,
  5 => 1,
  6 => 1,
  3 => 0,
  4 => 0,
  7 => 0,
  8 => 0,
)

Does anyone know how the foreach code block can be replaced with a functional programming alternative?


Solution

  • I think array_walk() partnered with a Union Operator and array_fill_keys() seems like a clean choice for this task:

    Code: (Demo)

    $mode[1] = [1, 2, 5, 6];
    $mode[0] = [3, 4, 7, 8];
    
    $result = []; // declare empty array so that union operator works
    array_walk($mode, function($a, $k) use (&$result) { $result += array_fill_keys($a, $k); });
    var_export($result);
    

    To avoid declaring any variables in the global scope, call array_reduce() on the first level keys and use those keys to access the second level subarray. (Demo)

    var_export(
        array_reduce(
            array_keys($mode),
            fn($result, $k) => $result += array_fill_keys($mode[$k], $k),
            []
        )
    );
    

    Output (from either snippet):

    array (
      1 => 1,
      2 => 1,
      5 => 1,
      6 => 1,
      3 => 0,
      4 => 0,
      7 => 0,
      8 => 0,
    )