我试图重现我们在office或adobe上打印页面时看到的效果。
例如,当你想打印第1页到第5页时,你写:1-5,如果你想打印外面的一页,你写:1-5,8
现在我爆炸string by ',':1-5/8
然后用'-'把每个结果分开,如果我得到了结果,我就从第一页循环到最后一页,并用逗号创建变量:
1、2、3、4、5、8
最后我用',',并使用数组唯一来擦除双精度值。
实现这一点需要一些时间,特别是当有很多'-'时。
也许有人有更简单的解决方法?
谢谢编辑:
$pages = "1-4,6-8,14,16,18-20";
$pages_explode = explode(',',$pages);
foreach($pages_explode as $page){
$page_explode = explode('-',$page);
if(!empty($page_explode[1])){
for ($i=$page_explode[0]; $i<=$page_explode[1] ; $i++) {
$page_final .= $i.',';
}
}else{
$page_final .= $page_explode[0].',';
}
}
$page_final = explode(',',$page_final);
$page_final = array_unique ($page_final);
foreach($page_final as $value){
echo $value.'<br>';
}
这是一个代码高尔夫挑战吗?
一个基本的方法对我来说似乎很好:
$input = '1-5,6-12,8';
$patterns = explode(',', $input);
$pages = [];
foreach ($patterns as $pattern) {
if (2 == count($range = explode('-', $pattern))) {
$pages = array_merge($pages, range($range[0], $range[1]));
} else {
$pages[] = (int)$pattern;
}
}
$uniquePages = array_unique($pages);
var_dump($uniquePages);
输出:
array (size=12)
0 => int 1
1 => int 2
2 => int 3
3 => int 4
4 => int 5
5 => int 6
6 => int 7
7 => int 8
8 => int 9
9 => int 10
10 => int 11
11 => int 12
必须删除重复项表明您的字符串中有重叠的范围。
如:1 - 5、2 - 9、7 - 15,8 10
你似乎处理了所有这些而没有考虑重叠的区域,最后试图通过昂贵的array_unique函数删除重复项。
您的代码应该记住结果范围的最小值和最大值,而不处理任何与此范围重叠的内容。
下面是演示这个想法的示例代码。但它肯定比你在你的问题中建议的代码快。您应该在那里添加部分,以处理需求中其他类型的分隔符(如果有的话)。
<?php
$ranges = "1-5,3-7,6-10,8,11";
$min = 10000;
$max = -1;
$numbers = array(); //Your numbers go here
//Just a utility function to generate numbers from any range and update margins
function generateNumbers($minVal, $maxVal) {
global $min, $max, $numbers;
for ($i = $minVal; $i <= $maxVal; $i++) {
array_push($numbers, $i);
if ($i < $min)
$min = $i;
if ($i > $max)
$max = $i;
}
}
//Seperate ranges
$sets = explode(",", $ranges);
//Go through each range
foreach($sets as $aSet) {
//Extract the range or get individual numbers
$range = explode("-", $aSet);
if (count($range) == 1) { //its an individual number. So check margins and insert
$aSet = intval($aSet);
if ($aSet < $min){
array_push($numbers, $aSet);
$min = $aSet;
}
if ($aSet > $max){
array_push($numbers, $aSet);
$max = $aSet;
}
continue; // <----- For single numbers it ends here
}
//Its a range
$rangeLow = intval($range[0]);
$rangeHigh = intval($range[1]);
//Adjusting numbers to omit cases when ranges fall right on the margins
if ($rangeLow == $min){
$rangeLow++;
}
else
if ($rangeLow == $max) {
$rangeLow--;
}
if ($rangeHigh == $min){
$rangeHigh++;
}
else
if ($rangeHigh == $max) {
$rangeHigh--;
}
//Check if below or above the generated range
if (($rangeLow < $min && $rangeHigh < $min) || ($rangeLow > $max && $rangeHigh > $max)) {
generateNumbers($rangeLow, $rangeHigh);
};
//Check if across the lower edge of the generated range
if ($rangeLow < $min && $rangeHigh > $min && $rangeHigh < $max) {
generateNumbers($rangeLow, $min - 1);
};
//Check if across the upper edge of the generated range
if ($rangeLow > $min && $rangeLow < $max && $rangeHigh > $max) {
generateNumbers($max + 1, $rangeHigh);
};
}
//Now just sort the array
print_r($numbers);
?>