我有这样的数组
$arr = array(1,1,1,2,2,3,3,1,1,2,2,3);
我找到了一个函数array_count_values
。但它会将所有相同的值组合在一起并对它们进行计数并打破序列。
$result[1] = 5
$result[2] = 4
$result[3] = 3
如何创建将遵循序列的count数组。我真正想要的结果是:
[1] = 3;
[2] = 2;
[3] = 2;
[2] = 2;
[3] = 1;
答案 0 :(得分:19)
PHP的array_count_values功能怎么样?
<?php
$array = array(1, "hello", 1, "world", "hello");
print_r(array_count_values($array));
?>
输出:
Array
(
[1] => 2
[hello] => 2
[world] => 1
)
答案 1 :(得分:4)
可以手动完成:
$arr = array(1,1,1,2,2,3,3,1,1,2,2,3);
$result = array();
$prev_value = array('value' => null, 'amount' => null);
foreach ($arr as $val) {
if ($prev_value['value'] != $val) {
unset($prev_value);
$prev_value = array('value' => $val, 'amount' => 0);
$result[] =& $prev_value;
}
$prev_value['amount']++;
}
var_dump($result);
答案 2 :(得分:2)
$current = null;
foreach($your_array as $v) {
if($v == $current) {
$result[count($result)-1]++;
} else {
$result[] = 1;
$current = $v;
}
}
var_dump($result);
答案 3 :(得分:1)
如果您不想要数组中的值
$result = explode( ',' , implode(',', array_count_values($your_array) ) );
答案 4 :(得分:1)
我的建议是在进入循环之前从数组中提取和删除第一个值,并使用一个临时数组($carry
)来跟踪每个新值是否与进位数组中的键匹配。如果是这样,请增加它。如果不是,则将完成的序列计数压入结果数组,并用新值覆盖进位,并将计数器设置为1。循环结束后,将挥之不去的进位压入结果集中。我的代码段不检查输入数组是否为空;如有必要,将该条件添加到您的项目中。
代码:(Demo)
$array = [1,1,1,2,2,3,3,1,1,2,2,3];
$result = [];
$carry = [array_shift($array) => 1];
foreach ($array as $value) {
if (isset($carry[$value])) {
++$carry[$value];
} else {
$result[] = $carry;
$carry = [$value => 1];
}
}
$result[] = $carry;
print_r($result);
输出:
Array
(
[0] => Array
(
[1] => 3
)
[1] => Array
(
[2] => 2
)
[2] => Array
(
[3] => 2
)
[3] => Array
(
[1] => 2
)
[4] => Array
(
[2] => 2
)
[5] => Array
(
[3] => 1
)
)
如果您想实施zerkms风格的按引用修改风格的技术,则以下代码段将提供与上述代码段相同的结果。
有效地,它将每个新遇到的值作为一个关联的单元素数组推入索引结果数组。由于推送的子数组被声明为变量($carry
,然后按引用分配(复合运算符:=&
)到结果数组,因此$carry
的增量将应用于深度结果数组中的嵌套值。输出数组在结构上需要额外的深度,以便可以可靠地存储多次出现的给定值。
代码:(Demo)
$result = [];
$carry = [];
foreach ($array as $value) {
if ($carry && key($carry) === $value) {
++$carry[$value];
} else {
unset($carry);
$carry = [$value => 1];
$result[] =& $carry;
}
}
unset($carry);
print_r($result);
可能没有必要取消引用变量$carry
的设置,但是如果该变量的范围内有该变量的潜在重用,则将引用与unset()
断开耦合很重要。
答案 5 :(得分:0)
以下是我的方式:
function SplitIntoGroups($array)
{
$toReturnArray = array();
$currentNumber = $array[0];
$currentCount = 1;
for($i=1; $i <= count($array); $i++)
{
if($array[$i] == $currentNumber)
{
$currentCount++;
}
else
{
$toReturnArray[] = array($currentNumber, $currentCount);
$currentNumber = $array[$i];
$currentCount = 1;
}
}
return $toReturnArray;
}
$answer = SplitIntoGroups(array(1,1,1,2,2,3,3,1,1,2,2,3));
for($i=0; $i<count($answer); $i++)
{
echo '[' . $answer[$i][0] . '] = ' . $answer[$i][1] . '<br />';
}
答案 6 :(得分:0)
function findRepetitions($times, $array) {
$values = array_unique($array);
$counts = [];
foreach($values as $value) {
$counts[] = ['value' => $value, 'count' => 0];
}
foreach ($array as $value) {
foreach ($counts as $key => $count) {
if ($count['value'] === $value) {
$counts[$key]['count']++;
}
}
}
$repetitions = [];
foreach ($counts as $count) {
if ($count['count'] === $times) {
$repetitions[] = $count['value'];
}
}
return $repetitions;
}