Reputation: 1694
I am not sure how to increase my email_actions
in this snippet:
$email_actions = 0;
array_walk(
$steps,
fn($step): int => !empty($step['settings']['type']) &&
$step['settings']['type'] === self::FLOWS_EMAIL_TYPE_ACTION
? $email_actions++
: false
);
dd($email_actions);
I get 0 as result when it should be 2. Tried to pass the variable by reference like:
fn($step, &$email_actions)
but is obviously not the right approach.
Upvotes: 0
Views: 1246
Reputation: 47991
When using functional-style array traversal to return anything other than an array of equal size, array_reduce()
is most appropriate. Arrow syntax becomes more enjoyable when global scope referencing is no longer needed. Demo
class Test
{
const FLOWS_EMAIL_TYPE_ACTION = 'foo';
function __construct(array $steps)
{
$email_actions = array_reduce(
$steps,
fn($result, $step) => $result
+ (($step['settings']['type'] ?? null) === self::FLOWS_EMAIL_TYPE_ACTION),
0
);
var_export($email_actions);
}
}
new Test([
['settings' => ['type' => 'bar']],
['settings' => ['type' => 'foo']],
[],
['settings' => ['type' => 'foo']],
]);
// 2
Upvotes: 1
Reputation: 43507
You should be using array_reduce
to get single value after iterating through all array
$email_actions = array_reduce(
$steps,
function ($carry, $step) {
if ($step['settings']['type'] === self::FLOWS_EMAIL_TYPE_ACTION) {
$carry++;
}
return $carry;
},
0
);
If you really need to use arrow functions:
$email_actions = array_count(
array_filter($steps, fn ($step) => $step['settings']['type'] === self::FLOWS_EMAIL_TYPE_ACTION)
);
Upvotes: 1
Reputation: 15247
fn
copies the variables that are automatically injected.
From documentation (check example 4) :
Arrow functions use by-value variable binding. This is roughly equivalent to performing a use($x) for every variable $x used inside the arrow function. A by-value binding means that it is not possible to modify any values from the outer scope. Anonymous functions can be used instead for by-ref bindings.
If you want to have a write access (a reference), you might need to use the old syntax :
$email_actions = 0;
array_walk(
$steps,
function($step) use (&$email_actions) : int
{
return !empty($step['settings']['type']) &&
$step['settings']['type'] === self::FLOWS_EMAIL_TYPE_ACTION
? $email_actions++
: false;
}
);
dd($email_actions);
Upvotes: 2