我想内爆一个数组,但有一点不同。我想用-
符号合并区间。如何做到这一点?(数组已排序!)
示例:
array(1,2,3,6,8,9) => "1-3,6,8-9"
array(2,4,5,6,8,10) => "2,4-6,8,10"
这应该适用于您:
首先,对于每次迭代,我们只需将当前迭代次数附加到$result
字符串:
$result .= $arr[$i];
在此之后,我们在while循环中检查数组(1)中是否存在下一个元素,并且它遵循当前迭代(2)中的数字。我们这样做,直到条件评估为false:
//(1)Check if next element exists (2)Check if next element follows up the prev one
┌───────┴───────┐ ┌───────────┴────────────┐
while(isset($arr[$i+1]) && $arr[$i] + 1 == $arr[$i+1] && ++$range)
$i++;
然后我们检查我们是否有一个范围(例如1-3
)。如果是,那么我们将短划线和范围的结束号附加到结果字符串:
if($range)
$result .= "-" . $arr[$i];
最后,我们还检查我们是否在数组的末尾,并且不再需要附加逗号:
if($i+1 < $l)
$result .= ",";
代码:
<?php
$arr = array(1,2,3,6,8,9);
$result = "";
$range = 0;
for($i = 0, $l = count($arr); $i < $l; $i++){
$result .= $arr[$i];
while(isset($arr[$i+1]) && $arr[$i] + 1 == $arr[$i+1] && ++$range)
$i++;
if($range)
$result .= "-" . $arr[$i];
if($i+1 < $l)
$result .= ",";
$range = 0;
}
echo $result;
?>
输出:
1-3,6,8-9
$oldArray=array(2,4,5,6,8,10);
$newArray=array();
foreach($oldArray as $count=>$val){
if($count==0){
//begin sequencing
$sequenceStart=$sequenceEnd=$val;
}
if($val==$sequenceEnd+1){
$sequenceEnd=$val;
continue;
}else{
if($sequenceEnd==$val){
//do nothing
continue;
}
}
//new sequence begins
//save new sequence
if($sequenceStart==$sequenceEnd){
//sequnce is a single number
$newArray[]=$sequenceEnd;
}else{
$newArray[]=$sequenceStart.'-'.$sequenceEnd;
}
//reset sequence
$sequenceStart=$sequenceEnd=$val;
}
//new sequence begins
//save new sequence
if($sequenceStart==$sequenceEnd){
//sequnce is a single number
$newArray[]=$sequenceEnd;
}else{
$newArray[]=$sequenceStart.'-'.$sequenceEnd;
}
//reset sequence
$sequenceStart=$sequenceEnd=$val;
return implode(',', $newArray);
没有这样的函数,因此您需要自己创建一个。我刚刚创建了一个示例函数,它可能看起来是什么样子,有很多可能的解决方案(如果它真的有效,就没有尝试,因为我在reach-atm中没有Web服务器)
<?php
function implodeNumberArray($arr) {
$lastValue = NULL;
$o = "";
//For each value in array
foreach ($arr as $v) {
if(!is_null($lastValue)) {
//If the number is following, do not paste it
if(($lastValue+1) == $v) {
//Check if the - sign was already posted
if(!(stripos(strrev($o), '-') === 0)) {
// - sign not pasted, therefore paste it
$o .= "-";
}
} else {
//Check if there is a - sign at the end
if((stripos(strrev($o), '-') === 0)) {
// Has - => paste 'prevValue,value''
$o .= $lastValue . "," . $v;
} else {
//Check if there is a , sign at the end
if((stripos(strrev($o), ',') === 0)) {
// No - but , => paste 'value'
$o .= $v;
} else {
// No - and no , => paste ',value'
$o .= ",".$v;
}
}
}
} else {
$o = $v;
}
$lastValue = $v;
}
//Check if the implode has the last number set correctly
if((stripos(strrev($o), '-') === 0)) {
$o .= $lastValue;
}
return $o;
}
echo implodeNumberArray(array(1,2,3,6,8,9));
?>
类似于答案@通过从连续月份创建连字符表达式来减少月份名称数组
如果数组为空或数字没有紧跟在前一个数字后面,则将数字作为引用推送到结果数组中。
当遇到连续数字时,通过保留前导数字并添加新连字符和新数字来重新生成引用字符串。
只需要一个循环和一个条件表达式。
代码:(演示)
function hyphenatedRanges(array $numbers): string
{
$result = [];
foreach ($numbers as $i => $number) {
if (isset($ref) && $number === $numbers[$i - 1] + 1) {
$ref = strtok($ref, "-") . "-$number";
} else {
unset($ref);
$ref = $number;
$result[] = &$ref;
}
}
return implode(',', $result);
}
echo hyphenatedRanges([1, 2, 3, 6, 8, 9]) . "'n"; // "1-3,6,8-9"
echo hyphenatedRanges([2, 4, 5, 6, 8, 10]); // "2,4-6,8,10"