【问题标题】:Get month list starting from a given month and ending to another?获取从给定月份开始到另一个月份结束的月份列表?
【发布时间】:2021-01-03 23:16:53
【问题描述】:

给定两个整数(每个表示一年中的月份),我需要生成一个整数数组,表示它们之间包含的月份范围。

要获取 12 月和 2 月之间的月份数,输入是:

$start = 12;
$finish = 2;

预期输出包含三个元素:12、1 和 2(因为是十二月、一月、二月)

我尝试过使用$arraylist = range($start, $finish);,但是当$start 的值大于$finish 的值时,输出的降序范围不正确,如下所示:[12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2]

以下是更多输入输出示例:

+--------+---------+-----------------------+
| $start | $finish |        $output        |
+--------+---------+-----------------------|
|    3   |    11   | [3,4,5,6,7,8,9,10,11] |
+--------+---------+-----------------------|
|   11   |     3   |     [11,12,1,2,3]     |
+--------+---------+-----------------------|
|    3   |     3   |           [3]         |
+--------+---------+-----------------------+

【问题讨论】:

  • 您想要的输出中的1 来自哪里?
  • @Nick 我为月份创建了一个数组,输入方法 2 编号,如果输入开始为 11,结束为 3,它将出现 [11,12,1,2,3 ]
  • start 为 3,finish 为 3 时的预期结果是什么?一个元素还是十三个元素?
  • @mickmackusa bcs 是月数,如果我们输入 3 和 3 作为范围,我希望返回输出为 3
  • 输入的质量不足以表达多年-因为输入值预计在1到12之间。如果您(或其他任何人)有不同的问题要求,请随时提问一个新问题,并说明如何需要新技术来扩展此处解决方案的功能。重要的是,这个问题的范围不要逐渐被遗忘。这是一个很好的,狭隘的问题,我希望它保持这种方式。我对这个问题收到 DV 并被关闭这一事实感到难过——我认为这个社区有太多的消极情绪。

标签: php arrays loops range increment


【解决方案1】:

这比递减所有内容、使用模数/算术以及将数字撞到首选值要简单得多。

  • 当两个数字不相同时循环。
  • 如果增加的数字增加到超过 12,请将其重置为 1。
  • 要使范围包含在内,请将结束编号推入数组。

代码 (Demo)

$array = [];
while ($start != $finish) {
    if ($start > 12) {
        $start = 1;
    }
    $array[] = $start++;  // increment AFTER pushing into the array
}
$array[] = $finish;
var_export($array);

我认为这不那么神秘。

输入/输出:

11, 3: [11, 12, 1, 2, 3]

3, 11: [3, 4, 5, 6, 7, 8, 9, 10, 11]

3, 3: [3]

附言下面的函数式风格也不觉得傻。将有 1 或 3 个函数调用,但我再次认为它很容易阅读,并且没有循环、没有临时变量,也没有递增/递减。

由于数据量保证很小,性能可能甚至不考虑(没有人会注意到此页面上的技术之间的性能差异)。最好选择一种可读的技术。

代码:(Demo)

$array = $start > $finish
    ? array_merge(range($start, 12), range(1, $finish))
    : range($start, $finish);

p.p.s.最后的考虑...如果有人更愿意使用 DateTime 技术处理月份逻辑,这也是明智的,并且可能会打开进一步扩展功能的大门(如果任务需要它)。缺点是这种技术的开销最大,因为它要实例化要使用的对象。

要使输出数组包含上个月,一个简单的解决方案是在末尾加 1。如果$begin 的值小于$finish 的值,那么我们将把这个值加12 推到明年。

代码:(Demo)

$begin = 11;
$finish = 3;

$period = new DatePeriod(
    DateTime::createFromFormat('m', $begin),
    new DateInterval('P1M'),
    DateTime::createFromFormat('m', $finish + ($begin > $finish ? 13 : 1))
);

foreach ($period as $obj) {
    $array[] = $obj->format('n');
}

var_export($array);

【讨论】:

    【解决方案2】:

    一种方法是使用模 12 算术。首先通过减一将$start$finish 转换为0-11 范围,然后增加$start 并推送到数组(如您所做的转换回范围1-12)直到$start == $finish

    $start = 12;
    $finish = 2;
    
    $arraylist = array();
    $start = --$start;
    $finish = --$finish;
    while ($start != $finish) {
        $arraylist[] = ++$start;
        $start = $start % 12;
    }
    $arraylist[] = ++$start;
    print_r($arraylist);
    

    输出:

    Array
    (
        [0] => 12
        [1] => 1
        [2] => 2
    )
    

    Demo on 3v4l.org

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-25
      • 1970-01-01
      • 2021-06-29
      相关资源
      最近更新 更多