【问题标题】:Get starts and ends of following values获取以下值的开始和结束
【发布时间】:2021-01-13 09:56:17
【问题描述】:

我有一个以下(又名有序)值的数组,以及一个选择值的数组:

$orderedValues = array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");

$pickedValues = array("Jan", "Mar", "Apr", "Jul", "Aug", "Sep", "Dec");

我想要的是有一个结果数组给我 每个 startend 以下选择的值.

  • $pickedValues 的排序方式已与 $orderedValues 相同。
  • 如果一个值是“单独”,则该值是开始,下一个值是结束;如果唯一的值是最后一个,那么它也是结束。

在给定的示例中,结果应如下所示:

$result = array(
    array( // Alone value, end is the next from the order
        "start" => "Jan",
        "end" => "Feb"
    ),
    array(
        "start" => "Mar",
        "end" => "Apr"
    ),
    array(
        "start" => "Jul",
        "end" => "Sep",
    ),
    array( // Alone and last
        "start" => "Dec",
        "end" => "Dec"
    )
);

我不知道如何实现这种分组。有什么提示吗?

【问题讨论】:

  • 伪代码将迭代选取的值,在排序值中搜索当前值,然后比较两者中的下一个值。如果不同,你有你的结局。如果没有,请继续前进,直到找到另一个或到达终点。
  • 或者您可以尝试先将选取的值重新排列成连续值组。之后就很容易找出结尾了(如果有多个元素,end 是最后一个,如果是单个,则从有序中找到下一个值)。

标签: php arrays sorting grouping


【解决方案1】:

基于@El_Vanja 的伪代码,这是我想出的:

$orderedValues = array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
$pickedValues = array("Jan", "Mar", "Apr", "Jul", "Aug", "Sep", "Dec");

$result = array();
$index = null;
foreach ( $pickedValues as $k => $v ) {
    if ( $index === null ) {
        $index = array_search($v, $orderedValues);
    }

    $orderIndex = array_search($v, $orderedValues);
    if ( $orderIndex + 1 == count($orderedValues) ) {
        // last value
        $result[] = array(
            "start" => $orderedValues[$index],
            "end" => $orderedValues[$orderIndex],
        );
    } else {
        $nextOrderValue = $orderedValues[$orderIndex + 1];
        $nextValue = $pickedValues[$k + 1];
        if ( $nextOrderValue != $nextValue ) {
            $result[] = array(
                "start" => $orderedValues[$index],
                "end" => $orderedValues[$orderIndex],
            );
            $index = null;
        }
    }
}
echo '<pre>' . print_r($result, true) . '</pre>';

根据live sample,看起来它正在工作。谢谢!

【讨论】:

  • 虽然这与您指定的有点不同。在您的答案中,中间元素以MayOct 结尾,但在问题中它们以AprSep 结尾。要么这不是您要查找的内容,要么应该编辑问题。
  • 编辑后现场样本完全关闭。所选值中的每个条目都只是复制为结尾。
  • 现场示例中的错字,现在已修复;)再次感谢