如何降低范围名单? [英] How to reduce lists of ranges?
问题描述
给定范围的名单,即: 1-3,5,6-4,31,9,19,10,25-20
我怎样才能将其降低到 1-6,9-10,19-25,31
?
Given a list of ranges ie: 1-3,5,6-4,31,9,19,10,25-20
how can i reduce it to 1-6,9-10,19-25,31
?
下面是我到目前为止已经做了,似乎有点复杂,所以 有没有更简单的/聪明的方法来做到这一点。
Here is what i've done so far, it seems a little bit complicated, so is there any simpler/clever method to do this.
$in = '1-3,5,6-4,31,9,19,10,25-20';
// Explode the list in ranges
$rs = explode(',', $in);
$tmp = array();
// for each range of the list
foreach($rs as $r) {
// find the start and end date of the range
if (preg_match('/(\d+)-(\d+)/', $r, $m)) {
$start = $m[1];
$end = $m[2];
} else {
// If only one date
$start = $end = $r;
}
// flag each date in an array
foreach(range($start,$end) as $i) {
$tmp[$i] = 1;
}
}
$str = '';
$prev = 999;
// for each date of a month (1-31)
for($i=1; $i<32; $i++) {
// is this date flaged ?
if (isset($tmp[$i])) {
// is output string empty ?
if ($str == '') {
$str = $i;
} else {
// if the previous date is less than the current minus 1
if ($i-1 > $prev) {
// build the new range
$str .= '-'.$prev.','.$i;
}
}
$prev = $i;
}
}
// build the last range
if ($i-1 > $prev) {
$str .= '-'.$prev;
}
echo "str=$str\n";
注:必须在PHP 5.1.6运行(我不能升级)
NB: it must run under php 5.1.6 (i can't upgrade).
仅供参考:再一个月present天数,使他们被限制在1-31
FYI : the numbers represent days of month so they are limited to 1-31.
从日期(1-3,6,7-8)
,我想重新获取列表(1-给定范围内3,6-8)
,所有的范围被重新计算,并下令。
From a given range of dates (1-3,6,7-8)
, i'd like obtain another list (1-3,6-8)
where all the ranges are recalculated and ordered.
推荐答案
也许不是最有效的,但不应该是太糟糕了你正在使用的值的有限范围:
Perhaps not the most efficient, but shouldn't be too bad with the limited range of values you're working with:
$in = '1-3,5,6-4,31,9,19,10,25-20';
$inSets = explode(',',$in);
$outSets = array();
foreach($inSets as $inSet) {
list($start,$end) = explode('-',$inSet.'-'.$inSet);
$outSets = array_merge($outSets,range($start,$end));
}
$outSets = array_unique($outSets);
sort($outSets);
$newSets = array();
$start = $outSets[0];
$end = -1;
foreach($outSets as $outSet) {
if ($outSet == $end+1) {
$end = $outSet;
} else {
if ($start == $end) {
$newSets[] = $start;
} elseif($end > 0) {
$newSets[] = $start.'-'.$end;
}
$start = $end = $outSet;
}
}
if ($start == $end) {
$newSets[] = $start;
} else {
$newSets[] = $start.'-'.$end;
}
var_dump($newSets);
echo '<br />';
这篇关于如何降低范围名单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!