Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>When mapping an anonymous function over an anonymous array, there is no way to access the keys:</p> <pre><code>array_map( function($val) use ($foo) { /* ... */ }, array(key1 =&gt; val1, key2 =&gt; val2, /* ... */)); </code></pre> <p>array_reduce doesn't get access to the keys either. array_walk can access keys, but the array is passed by reference, which requires a layer of indirection.</p> <p>Some solutions are:</p> <h3>Array of pairs</h3> <p>This is bad, since we're changing the original array. Plus the boilerplate "array()" calls increase linearly with the length of the array:</p> <pre><code>array_map( function($pair) use ($foo) { list($key, $val) = $pair; /* ... */ }, array(array(key1, val1), array(key2, val2), /* ... */)); </code></pre> <h3>Temporary variable</h3> <p>We're acting on the original array, and the boilerplate is constant, but we can easily clobber an existing variable:</p> <pre><code>$i_hope_this_does_not_conflict = array(key1 =&gt; val1, key2 =&gt; val2, /* ... */); array_map( function($key, $val) use ($foo) { /* ... */ }, array_keys($i_hope_this_does_not_conflict), $i_hope_this_does_not_conflict); unset($i_hope_this_does_not_conflict); </code></pre> <h3>One-shot function</h3> <p>We can use function scope to prevent clobbering existing names, but have to add an extra layer of "use":</p> <pre><code>call_user_func( function($arr) use ($foo) { return array_map(function($key, $val) use ($foo) { /* ... */ }, array_keys($arr), $arr); }, array(key1 =&gt; val1, key2 =&gt; val2, /* ... */)); </code></pre> <h3>Multi-argument one-shot function</h3> <p>We define the function we're mapping in the original scope to prevent the "use" boilerplate):</p> <pre><code>call_user_func( function($f, $arr) { return array_map($f, array_keys($arr), $arr); }, function($key, $val) use ($foo) { /* ... */ }, array(key1 =&gt; val1, key2 =&gt; val2, /* ... */)); </code></pre> <h3>New function</h3> <p>The interesting thing to note is that our last one-shot function has a nice, generic signature and looks a lot like array_map. We might want to give this a name and re-use it:</p> <pre><code>function array_mapk($f, $arr) { return array_map($f, array_keys($arr), $arr); } </code></pre> <p>Our application code then becomes:</p> <pre><code>array_mapk( function($key, $val) use ($foo) { /* ... */ }, array(key1 =&gt; val1, key2 =&gt; val2, /* ... */)); </code></pre> <h3>Indirect Array Walk</h3> <p>When writing the above I'd ignored array_walk since it requires its argument to be passed by reference; however, I've since realised that it's easy to work around this using call_user_func. I think this is the best version so far:</p> <pre><code>call_user_func( 'array_walk', array(key1 =&gt; val1, key2 =&gt; val2, /* ... */), function($val, $key) use ($foo) { /* ... */ }); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload