我有一个像这样的数组:
Array
(
[0] => Jan
[1] => Feb
[2] => Mar
[3] => Apr
[4] => May
[5] => Jun
[6] => Sep
[7] => Oct
[8] => Dec
)
我需要把它转换成
Array
(
[0] => "Jan - Jun"
[1] => "Sep - Oct"
[2] => "Dec"
)
月份总是有序的,但由于数组是动态的,我想不出一个好的有效方法,除了用 date_parse 将每个月转换为数字,然后与它周围的月份结合!但我真的很困惑该怎么做,有什么想法吗?
这样的事情怎么样:
function findConsecutiveMonths(array $input) {
// Utility list of all months
static $months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
$chunks = array();
for ($i = 0; $i < 12; $i++) {
// Wait until the $i-th month is contained in the array
if (!in_array($months[$i], $input)) {
continue;
}
// Find first consecutive month that is NOT contained in the array
for ($j = $i + 1; $j < 12; $j++) {
if (!in_array($months[$j], $input)) {
break;
}
}
// Chunk is from month $i to month $j - 1
$chunks[] = ($i == $j - 1) ? $months[$i] : $months[$i] .' - '. $months[$j - 1];
// We know that month $j is not contained in the array so we can set $i
// to $j - the search for the next chunk is then continued with month
// $j + 1 because $i is incremented after the following line
$i = $j;
}
return $chunks;
}
应该这样做:
function combine_months($months) {
$all_months = array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
$target = array();
$start = null;
for ($i = 0; $i<12; $i++) {
if (!in_array($all_months[$i], $months) && $start != null) {
if ($start == null) {
$target[] = $all_months[$i-1];
}
else {
$target[] = sprintf("%s - %s", $start, $all_months[$i-1]);
}
$start = null;
}
elseif ($start == null) {
$start = $all_months[$i];
}
}
if ($start != null) {
$target[] = $start;
}
return $target;
}
$test = combine_months(array("Jan","Feb","Mar","Apr","May","Jun","Sep","Oct","Dec"));
var_dump($test);
它迭代所有可用的月份,记住第一个共同的月份,当缺少月份时添加到目标数组。
作为 this answer of mine 的改编版,使用查找数组和引用将连续的月份名称推送到正确的元素中——使用
strtok()
和串联以确保始终正确更新范围的末尾。
这个片段会表现很好,因为它只使用一个循环并且没有
in_array()
调用(PHP 的一种搜索数组的慢形式)。
代码:(演示)
$lookup = array_flip(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);
$months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Sep', 'Oct', 'Dec'];
$result = [];
foreach ($months as $month) {
if (isset($ref) && $lookup[$month] === $lookup[$last] + 1) {
$ref = strtok($ref, "-") . "-$month";
} else {
unset($ref);
$ref = $month;
$result[] = &$ref;
}
$last = $month;
}
var_export($result);
或者以不同的方式编写以利用
$i
而不是 $last
因为输入数组已被索引。 (演示)
$result = [];
foreach ($months as $i => $month) {
if ($i && $lookup[$month] === $lookup[$months[$i - 1]] + 1) {
$ref = strtok($ref, "-") . "-$month";
} else {
unset($ref);
$ref = $month;
$result[] = &$ref;
}
}
var_export($result);
如果您的输入数组需要容纳循环引用,请使用带 12(一年中的月数)的模数运算符以确保一月“回顾”到十二月(演示)
if (isset($ref) && $lookup[$month] === ($lookup[$last] + 1) % 12) {