统计一个二维数组中某一列中唯一值的出现次数。

10
我目前有以下数组:
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
        )
)

我正在尝试创建一个新的数组,以不同的“group”值作为键,然后计算每个组中有多少个元素,得到以下结果:
Array
(
    [1] => 2
    [2] => 2
    [3] => 1
)

我尝试使用了以下方法,但是我收到了未定义索引的警告信息。
$newArr = array();
foreach ($details['user_groups'] as $key => $value) {
    $newArr[$value['user_groups']]++;
}

只是为了确认,您是在尝试从第一个数组中获取“group”吗? - user745235
是的,所以将第一个数组中的组范围(即1-3)作为新数组的键,然后再次从第一个数组中计算每个组中有多少个。 - lethalMango
6个回答

15
这可以通过简单的迭代来完成。
$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;
}

### PHP 5.5 更新
在 PHP 5.5 中,新增了 array_column() 函数,用于从二维数组中聚合内部键,这样可以简化为:
$counts = array_count_values(array_flip(array_column($array, 'group')));

1
$counts[$subarr['group']++]; - user745235
我尝试了那个Michael,使用我在问题中包含的代码,但是我收到了未定义索引警告。 - lethalMango
@gerep 不是你想的那样 :) 我少了一个括号,但已经修复了。 - Michael Berkowski
有没有不用循环数组的另一种方法? - Oki Erie Rinaldi
如果您有PHP 5.5(其中包含array_column()),则可以执行array_count_values(array_flip(array_column($array, 'group'))). 否则,请参见另一个用户发布的array_map()示例。 - Michael Berkowski
显示剩余2条评论

5

使用简单的array_map函数即可实现。

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

$array2 = (array_count_values($array));

print_r($array2);

亲爱的@Vijaysinh Parmar,您在哪里定义了$array1? - Raham
你可以将问题数组称为 $array1。 - Vijaysinh Parmar
亲爱的@Vijaysinh Parmar,非常感谢您的迅速回复。我之前使用了自己的方法,但在看到您的回复后,我更喜欢您的方法。谢谢。 - Raham

2

你的初始尝试很接近。只是在循环内部使用了错误的键:

$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']]++;
}

所以这是一个错别字问题吗?我不赞成生成警告/通知的代码片段。 - mickmackusa

0

尝试这种简单而有效的方法

$count = call_user_func_array('array_merge_recursive', $Array);
echo count($count['user']).'<br>';
echo count($count['group']).'<br>';

0
$output = array();
  foreach($data as $key => $value){
    $output[$value['group']]['count']++;
}

$final = array();
foreach($output as $key => $value){
    $final[$key] = $value['count'];    
}

print_r($final);

//out put result:=========
Array(
    [1] => 2
    [2] => 2
    [3] => 1
)

这是“输出结果”还是“最终输出”?请描述为什么这是解决问题的方法(与现有答案的更功能性方法相比),以及您的方法如何工作。 - greybeard

0

这个任务只需要两个本地函数调用。使用array_column()隔离所需的数据列,然后使用array_count_values()计算出现次数。这是我在我的项目中编写此任务的唯一方式。

使用array_column()的附加好处是,如果您的子数组中有些不包含目标列键,则不会生成任何通知/警告。如果您使用常见的循环技术或array_map/array_walk(),则可能需要编写条件检查以防止通知/警告。

代码:(演示

$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'))
);

输出:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接