10

I currently have the following array:

Array(
    [0] => Array
        (
            [user] => Name 1
            [group] => 1
        )
    [1] => Array
        (
            [user] => Name 2
            [group] => 1
        )
    [2] => Array
        (
            [user] => Name 3
            [group] => 2
        )
    [3] => Array
        (
            [user] => Name 4
            [group] => 2
        )
    [4] => Array
        (
            [user] => Name 5
            [group] => 3
        )
)

I am attempting to create a new array with the various group values as the key, then count how many are in each group to give the following:

Array
(
    [1] => 2
    [2] => 2
    [3] => 1
)

I have attempted to use the following, however I get undefined index warnings:

$newArr = array();
foreach ($details['user_groups'] as $key => $value) {
    $newArr[$value['user_groups']]++;
}
2
  • just to make sure, you are trying to get the group from the first array? Commented Apr 18, 2012 at 18:32
  • Yeah, so the range of groups from the first array (i.e. 1-3) as the keys of the new array and then count how many are in each group, again from the first array Commented Apr 18, 2012 at 18:34

4 Answers 4

15

This can be done with a simple iteration:

$counts = array();
foreach ($array as $key=>$subarr) {
  // Add to the current group count if it exists
  if (isset($counts[$subarr['group']]) {
    $counts[$subarr['group']]++;
  }
  // or initialize to 1 if it doesn't exist
  else $counts[$subarr['group']] = 1;

  // Or the ternary one-liner version 
  // instead of the preceding if/else block
  $counts[$subarr['group']] = isset($counts[$subarr['group']]) ? $counts[$subarr['group']]++ : 1;
}

###Update for PHP 5.5

In PHP 5.5, which has added the array_column() function to aggregate an inner key from a 2D array, this can be simplified to:

$counts = array_count_values(array_flip(array_column($array, 'group')));
Sign up to request clarification or add additional context in comments.

7 Comments

$counts[$subarr['group']++];
I did try that Michael using the code I included on my question, however I get undefined index warnings.
@gerep Not as you have it :) I was missing a bracket, but already fixed it.
@lethalMango Did you try the current version I have there? It will not give undefined index warnings. Initially, I hit the save button before completing the if/else
Sorry I saw the first version :) Works a charm, I guessed I had missed something obvious! Thanks
|
5

This can be done with a simple array_map function

$array = array_map(function($element){
    return $element['group'];
}, $array1);

$array2 = (array_count_values($array));

print_r($array2);

3 Comments

Dear,@Vijaysinh Parmar where you defined $array1?
you can refer question array as $array1.
Dear @Vijaysinh Parmar thank you for such a prompt response.I used my own one but after your reply I prefer yours.Thank you
2

Your initial attempt was close. You were simply using the wrong key inside the loop:

$newArr = array();
foreach ($details['user_groups'] as $key => $value) {
        // What you were using:
        // $newArr[$value['user_groups']]++;

        // What you should be using:
        $newArr[$value['group']]++;
}

1 Comment

So this was a typo question? I do not endorse snippets that generate Warnings/Notices.
0

You only need two native function calls for this task. Isolate the desired column of data with array_column(), then count the occurrences with array_count_values(). This is the only way that I would code this task in one of my projects.

The added benefit of using array_column() is that if some of your subarrays do not contain the targeted column key, then there will be no Notice/Warning generated. If you were to use a common looping technique or array_map/array_walk() instead, you might need to write conditional checks to prevent the Notices/Warnings.

Code: (Demo)

$array = [
    ['user' => 'Name 1', 'group' => 1],
    ['user' => 'Name 2', 'group' => 1],
    ['user' => 'Name 3', 'group' => 2],
    ['user' => 'Name 4', 'group' => 2],
    ['user' => 'Name 5', 'group' => 3],
];

var_export(
    array_count_values(array_column($array, 'group'))
);

If you have a good reason to use a manual loop (such as summing the encountered values or multiplying values by a quantity before adding), just null coalesce to 0 to prevent PHP complaining about incrementing/adding-to an undeclared variable. Demo

$result = [];
foreach ($array as ['group' => $g]) {
    $result[$g] = ($result[$g] ?? 0) + 1;
}
var_export($result);

Output (from either snippet):

array (
  1 => 2,
  2 => 2,
  3 => 1,
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.