Php 是否可能将数组键分组到数字范围?

Php 是否可能将数组键分组到数字范围?,php,arrays,Php,Arrays,我有以下数组: ( [25] => 1 [26] => 3 [10] => 2 [24] => 1 ) 它是使用PHP中的函数创建的 实际的原始数组是这样的,在数组计数值之前 Array ( [0] => 26 [1] => [2] => 18 [3] => 28 [4] => 22 [5] => 21 [6] => 26 [7]

我有以下数组:

(
    [25] => 1
    [26] => 3
    [10] => 2
    [24] => 1
)
它是使用PHP中的函数创建的

实际的原始数组是这样的,在数组计数值之前

Array
(
    [0] => 26
    [1] => 
    [2] => 18
    [3] => 28
    [4] => 22
    [5] => 21
    [6] => 26
    [7] => 
    [8] => 
    [9] => 
    [10] => 
    [11] => 
    [12] =>
    [13] =>
    [14] =>
    [15] =>
    [16] =>
    [17] =>
    [18] =>
    [19] =>
    [20] =>
)
这些都是年龄,那么我如何将它们分为年龄组呢

假设我想要以下年龄组:
32

它应该看起来:

(
[<= 18] => 1
[19-26] => 4
[27-32] => 2
[ > 32] => 1
)
(
[ 1
[19-26] => 4
[27-32] => 2
[ > 32] => 1
)
有现成的功能吗

我的解决方案:
1繁琐的方法是创建年龄组的变量。如果键匹配range
($min有趣的问题。这是我的解决方案。首先,定义年龄范围数组:

$age_ranges = array(
    array( 0, 18),
    array( 19, 26),
    array( 27, 32),
    array( 33, 150) // I use 150 as the "max" age
);
然后,我们有了您的
array\u count\u values()
输出:

$array_count_values = array( 25 => 1, 26 => 3, 10 => 2, 24 => 1); // From OP
现在,我们创建一个包含所有年龄的数组,其中键是年龄,值是具有该年龄的人数。下一步需要按键排序

$all_ages = $array_count_values + array_fill( 0, 150, 0);
ksort( $all_ages);
最后,我循环所有年龄范围,从
$all_ages
数组中切掉年龄范围,并将它们的值相加,生成一个年龄范围数组,其值对应于属于该年龄范围的人数

$result = array();
foreach( $age_ranges as $range) {
    list( $start, $end) = $range;
    $result["$start-$end"] = array_sum( array_slice( $all_ages, $start, $end - $start + 1));
}
A
打印($result);

编辑:由于您仍然可以访问原始数组,因此您只需计算最后有多少“未知数”:

$result['unknown'] = count( array_filter( $original_array,  function( $el) { 
    return empty( $el); 
}));

如果只想使用以前的数组
数组\u count\u values()
,可以使用

$ages = array(
    0 => 26,
    1 => 18,
    2 => 28,
    3 => 22,
    4 => null,
    5 => 21,
    6 => 26,
    7 => null);
创建一个空白数组以填充

$final = array(
    'unknown' => 0,
    '18' => 0,
    '19_26' => 0,
    '27_32' => 0,
    '32' => 0,
);

array_walk($ages, function($age, $i, $final) {
    if (!$age) { $final['unknown']++; return; }
    if ($age <= 18) { $final['18']++; return; }
    if ($age <= 26) { $final['19_26']++; return; }
    if ($age <= 32) { $final['27_32']++; return; }
    if ($age > 32) { $final['32']++; return; }
}, &$final);

看到所有这些解决方案后,我想为什么不在原始数组中使用Regex呢

$ages = array(25, 26, 10, 24, 10, 26, 26, 32, 32, 54, 84, 4, 18, 5, 98, 27);
$string = '#'. implode('#', $ages) . '#';
preg_match_all('/(#[0-9]#|#1[0-7]#)|(#1[8-9]#|#2[0-6]#)|(#2[7-9]#|#3[0-2]#)|(#3[3-9]#|#[4-9][0-9]#|#1[0-5][0-9]#)/', $string, $groups);
$age_ranges = array('0-17' => count(array_filter($groups[1])), '18-26' => count(array_filter($groups[2])), '27-32'
 => count(array_filter($groups[3])), '33-159' => count(array_filter($groups[4])));

print_r($age_ranges);
输出:

Array
(
    [0-17] => 2
    [18-26] => 3
    [27-32] => 1
    [33-159] => 2
)

这听起来像是map reduce的完美案例

地图步骤:将每个年龄段转换为4个范围中的一个

减少步骤:将范围转换为范围的结果数组

让我们试一下:

$map = function($age) {
    if (!$age) {
        return 'unknown';
    } elseif ($age <= 18) {
        return '<= 18';
    } elseif ($age <= 26) {
        return '19-26';
    } elseif ($age <= 32) {
        return '26-32';
    }
    return '> 32';
}
这很简单。如果你想支持动态范围,那么你应该有一些逻辑来检查年龄是否未设置(然后将其初始化为
0

所以现在,把所有这些放在一起:

$array = array(12, 63, 24, 34, 12, 10, 19,); // Your ages
$data = array_map(function($age) {
    if (!$age) {
        return 'unknown';
    } elseif ($age <= 18) {
        return '<= 18';
    } elseif ($age <= 26) {
        return '19-26';
    } elseif ($age <= 32) {
        return '26-32';
    }
    return '> 32';
}, $array);
$result = array_reduce($data, function($result, $age) {
    $result[$age]++;
    return $result;
}, array('unknown' => 0, '<= 18' => 0, '19-26' => 0, '26-32' => 0, '> 32' => 0));
$array=array(12,63,24,34,12,10,19),//你的年龄
$data=数组\映射(函数($age){
如果(!$age){
返回“未知”;
}elseif($0岁,'19-26'=>0岁,'26-32'=>0岁,'32'=>0岁);
然后产生:

array(4) { 
    ["unknown"]=> int(0)
    ["<= 18"]=> int(3) 
    ["19-26"]=> int(2) 
    ["26-32"]=> int(0) 
    ["> 32"]=> int(2) 
}
数组(4){
[“未知”]=>int(0)
[“32”]=>int(2)
}

没有内置的PHP函数来对数组进行分组排序。您确定预期的输出正确吗?根据
数组计数值()
output,您有2人在<18类,5人在19-26类,其余的类中没有人。@nickb output是错误的,我在这里粘贴了一个错误的想法…OP可以使用
array\u map()
来避免“foreach循环”,+1 nickb!@HamZaDzCyberDeV:我看不出
array_map
在这里有什么帮助。另外
foreach
可能更快。那么未定义的结果呢?很抱歉,我没有在OP中写这篇文章。但是我必须考虑空键,因为它们是没有指定年龄的用户。但对于饼图,我正在做的工作,也必须包括空键那个。@Sando-那个是在你的
数组\u count\u values()
数组中返回的吗?@SandroDzneladze我更新了我的答案来解释未知的东西。
$reduce = function($result, $age) {
    $result[$age]++;
    return $result;
}
$array = array(12, 63, 24, 34, 12, 10, 19,); // Your ages
$data = array_map(function($age) {
    if (!$age) {
        return 'unknown';
    } elseif ($age <= 18) {
        return '<= 18';
    } elseif ($age <= 26) {
        return '19-26';
    } elseif ($age <= 32) {
        return '26-32';
    }
    return '> 32';
}, $array);
$result = array_reduce($data, function($result, $age) {
    $result[$age]++;
    return $result;
}, array('unknown' => 0, '<= 18' => 0, '19-26' => 0, '26-32' => 0, '> 32' => 0));
array(4) { 
    ["unknown"]=> int(0)
    ["<= 18"]=> int(3) 
    ["19-26"]=> int(2) 
    ["26-32"]=> int(0) 
    ["> 32"]=> int(2) 
}