如何统计数组中连续重复的值?
我有一个像这样的数组:
$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
如何对每组连续值进行分组并计算每个序列的长度?请注意,数字 1
、2
和 3
有两组序列。
我期望生成的数据需要类似于以下内容:
[1] = 3;
[2] = 2;
[3] = 2;
[1] = 2;
[2] = 2;
[3] = 1;
I have an array like this:
$arr = array(1, 1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3);
I found the function array_count_values()
, but it will group all of the same values and count the occurrences without respecting breaks in the consecutive sequences.
$result[1] = 5
$result[2] = 4
$result[3] = 3
How can I group each set of consecutive values and count the length of each sequence? Notice there are two sets of sequences for the numbers 1
, 2
, and 3
.
The data that I expect to generate needs to resemble this:
[1] = 3;
[2] = 2;
[3] = 2;
[1] = 2;
[2] = 2;
[3] = 1;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
可以简单地手动完成:
It can be done simply manually:
PHP 的 array_count_values 函数怎么样?
输出:
What about PHP's array_count_values function?
output:
我的建议是在进入循环之前从数组中提取并删除第一个值,并使用临时数组 (
$carry
) 来跟踪每个新值是否与进位数组中的键匹配。如果是这样,请增加它。如果没有,则将已完成的序列计数推送到结果数组中,并用新值覆盖进位并将计数器设置为 1。当循环结束时,将延迟进位推送到结果集中。我的代码片段不检查输入数组是否为空;如有必要,请将该条件添加到您的项目中。代码:(演示)
输出:(压缩以减少页面膨胀)
如果您更愿意实现 zerkms 风格,通过引用修改样式技术,以下代码片段提供与上述代码片段相同的结果。
实际上,它将每个新遇到的值作为关联的单元素数组推送到索引结果数组中。由于推送的子数组被声明为变量 (
$carry
),然后通过引用 (= &
) 分配给结果数组,因此$carry 递增
将应用于结果数组中的深层嵌套值。输出数组在其结构中需要额外的深度,以便可以可靠地存储多次出现的给定值。代码:(Demo)
循环后取消设置引用变量
$carry
可能不会必要的,但如果在变量的作用域内可能会重复使用该变量,则使用unset()
取消引用将很重要。只是为了好玩,这里有一个可怕的正则表达式注入方法,适用于示例数据:演示
My suggestion is to extract&remove the first value from the array prior to entering the loop and use a temporary array (
$carry
) to track whether each new value matches the key in the carry array. If so, increment it. If not, push the completed sequence count into the result array and overwrite the carry with the new value and set the counter to 1. When the loop finishes, push the lingering carry into the result set. My snippet does not check if the input array is empty; if necessary, add that condition to your project.Code: (Demo)
Output: (condensed to reduce page bloat)
If you'd rather implement a zerkms-style, modify-by-reference style technique, the following snippet provides the same result as the above snippet.
Effectively, it pushes every newly encountered value as an associative, single-element array into the indexed result array. Because the pushed subarray is declared as a variable (
$carry
) then assigned-by-reference (= &
) to the result array, incrementation of$carry
will be applied to the deeply nested value in the result array. The output array requires the additional depth in its structure so that a given value which occurs multiple times can be reliably stored.Code: (Demo)
Unsetting the reference variable
$carry
after the loop may not be necessary, but if there is any potential re-use of that variable within the variable's scope, it will be important to uncouple the reference withunset()
.And just for fun, here is a hideous regex-infused approach that works with the sample data: Demo
这是我的做法:
Here is the way that I would do it: