How can I prevent duplicating the same block of code for each value that I want to search for?
I want to create a new array ($result) by counting for specific values within another multi-dimensional array ($data).
$result = array();
$result['Insulin'] = count(array_filter($data,function ($entry) {
return ($entry['choice'] == 'Insulin');
}
)
);
$result['TZD'] = count(array_filter($data,function ($entry) {
return ($entry['choice'] == 'TZD');
}
)
);
$result['SGLT-2'] = count(array_filter($data,function ($entry) {
return ($entry['choice'] == 'SGLT-2');
}
)
);
$data array example:
array(2) {
[0]=>
array(9) {
["breakout_id"]=>
string(1) "1"
["case_id"]=>
string(1) "1"
["stage_id"]=>
string(1) "1"
["chart_id"]=>
string(1) "1"
["user_id"]=>
string(2) "10"
["region"]=>
string(6) "Sweden"
["choice"]=>
string(7) "Insulin"
["switched_choice"]=>
NULL
["keep"]=>
string(1) "1"
}
[1]=>
array(9) {
["breakout_id"]=>
string(1) "1"
["case_id"]=>
string(1) "1"
["stage_id"]=>
string(1) "1"
["chart_id"]=>
string(1) "1"
["user_id"]=>
string(1) "7"
["region"]=>
string(6) "Sweden"
["choice"]=>
string(7) "Insulin"
["switched_choice"]=>
NULL
["keep"]=>
string(1) "1"
}
}
You may convert your anonymous function into a closure with the use keyword. Pass in a string variable for the value you want to match.
// Array of strings to match and use as output keys
$keys = array('Insulin','TZD','SGLT-2');
// Output array
$result = array();
// Loop over array of keys and call the count(array_filter())
// returning the result to $result[$key]
foreach ($keys as $key) {
// Pass $key to the closure
$result[$key] = count(array_filter($data,function ($entry) use ($key) {
return ($entry['choice'] == $key);
}));
}
Converting your var_dump() to an array and running this against it, the output is:
Array
(
[Insulin] => 2
[TZD] => 0
[SGLT-2] => 0
)
You can simplify it with array_count_values() as well:
$result2 = array_count_values(array_map(function($d) {
return $d['choice'];
}, $data));
print_r($result2);
Array
(
[Insulin] => 2
)
If you need zero counts for the missing ones, you may use array_merge():
// Start with an array of zeroed values
$desired = array('Insulin'=>0, 'TZD'=>0, 'SGLT-2'=>0);
// Merge it with the results from above
print_r(array_merge($desired, $result2));
Array
(
[Insulin] => 2
[TZD] => 0
[SGLT-2] => 0
)
Not the most efficient algorithm in terms of memory, but you can map each choice onto a new array and then use array_count_values():
$result = array_count_values(array_map(function($item) {
return $item['choice'];
}, $data));
Since 5.5 you can simplify it a little more by using array_column():
$result = array_count_values(array_column($data, 'choice'));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With