Php count + array_filter multiple values ​​in a multidimensional array

How can I prevent duplication of the same block of code for each value I want to find?

I want to create a new array ($ result) by counting for specific values ​​in another multidimensional 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"
  }
}
+3
source share
3 answers

You can convert your anonymous function to closure using a keyword use. Pass a string variable for the value you want to map.

// 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 var_dump()to an array and running it against it, the output:

Array
(
    [Insulin] => 2
    [TZD] => 0
    [SGLT-2] => 0
)

You can also simplify it with array_count_values():

$result2 = array_count_values(array_map(function($d) {
  return $d['choice'];
}, $data));

print_r($result2);

Array
(
    [Insulin] => 2
)

, 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
)
+2

, , array_count_values():

$result = array_count_values(array_map(function($item) {
  return $item['choice'];
}, $data));

5.5 , array_column():

$result = array_count_values(array_column($data, 'choice'));
+2

You can easily simplify your code if counting is your only goal:

$result = array();

foreach ($data AS $row) {
  if (!isset($result[$row['choice']])) {
    $result[$row['choice']] = 1;
  } else {
    $result[$row['choice']]++;
  }
}

If you want to count only certain options, you can change the above code to something like this:

$result = array();
$keys = array('Insulin', 'TZD', 'SGLT-2');

foreach ($data AS $row) {
  if (!in_array($row['choice'], $keys)) {
    continue;
  }

  if (!isset($result[$row['choice']])) {
    $result[$row['choice']] = 1;
  } else {
    $result[$row['choice']]++;
  }
}
0
source

All Articles