【问题标题】:Compare arrays and compact it if in same order比较数组并按相同顺序压缩它
【发布时间】:2015-11-05 04:12:41
【问题描述】:

假设我们有这些数组:

$a = array("B", "C", "D", "E");
$b = array("A", "B" , "C", "D", "E", "F", "G", "H", "I");

然后我想检查来自$a 的子序列是否在$b 中是连续的。如果是并且超过 3 个元素,我想用破折号输出它们,例如X-Y。在所有其他情况下,我只想打印出逗号分隔的值。

因此,上述$a 数组的预期输出为:

B-E

另一个例子:

$a = array("B", "C", "D", "F", "H");
//Same $b array to check if a sub sequence of $a appears in $b consecutive

预期输出:

B-D, F, H

我在 foreach 循环中尝试了一些疯狂的 foreach,它检查两个数组中的值并设置指针,然后比较指针。感觉太复杂了,现在我头疼。

我觉得我错过了一些明显的东西,这是超级简单的事情。

编辑:这是我目前的进度。

$pointer = count($b);
$a = array("B", "C" , "D", "E");
$b = array("A", "B", "C" , "D", "E", "F", "G");

foreach ($b as $key => $bb) {
    if ($a[0] == $bb) {
        $pointer = $key;
    }
}


$d = array();
$d[] = $a[0];
foreach ($a as $key => $aa) {
    if ($aa == $b[$pointer+$key]) {
        $pointer = $key;
    } else {
        $d[] = "-".$aa;
        $pointer++;
    }
}
echo implode('',$d);

编辑 2: 这些值不仅仅是字母。它们是字符串,可以有不同的长度。 (“AA”、“b”、“lk”)例如。

【问题讨论】:

  • 我尝试了一些疯狂的 foreach 向我们展示疯狂的代码,我们将向你展示如何让疯狂的代码工作
  • 不清楚你到底想要什么,你想跳过任何特定的值还是几个值?请说清楚
  • @Rizier123 我添加了我在放弃循环后尝试制作的代码。
  • @M3ghana 我以为我很清楚。如果第一个数组在第二个数组($a 和 $b)中以相同的顺序在某个点具有相同的值,则您只显示数组中的第一个和最后一个值。如果第一个数组跳过了第二个数组中的一些值,它仍应以相同的方式显示这些值,但单独列出奇数。可能有一个词可以描述这一点,但我不知道。
  • 仅供参考:您可以接受对您帮助最大并解决了您的问题的答案 (meta.stackexchange.com/q/5234)

标签: php arrays loops for-loop foreach


【解决方案1】:

这应该适合你:

只需遍历整个数组,在每次迭代中只打印迭代的当前值。

然后在while循环中检查数组中是否还有下一个元素,isset() AND 如果当前数组元素等于下一个元素。

这可以很简单地做到,通过使用ord()获取字符的ASCII值并在比较之前添加一个。

如果它们相等,则增加 $i$followUp

在循环之后,您可以检查是否有超过 1 个字符跟随当前字符(例如:AD = 0 跟进、ABD = 1 次跟进;ABC = 2 次跟进)。如果您有超过 1 个,则打印此值并在其间添加破折号。

那么如果不是数组的末尾也打印一个逗号来分隔值。

在 for 循环结束时,只需检查您是否只有 1 个后续操作,并通过分配 0 来反转 $i + 重置 $followUp 的增量。

<?php

    $a = array("A", "B", "C", "F", "H", "K", "L", "M", "N", "R", "S", "X", "Y", "Z");

    $length = count($a);
    $followUp = 0;
    for($i = 0; $i < $length; $i++) {

        echo $a[$i];

        while(isset($a[$i+1]) && (ord($a[$i]) + 1) == ord($a[$i+1])){
            ++$followUp;
            ++$i;
        }

        if($followUp > 1)
            echo "-" . $a[$i];

        if($i != count($a) - 1)
            echo ",";

        if($followUp == 1) --$i;
        $followUp = 0;

    }

?>

输出:

A-C,F,H,K-N,R,S,X-Z

编辑:

如果你想检查子序列是否在另一个数组中以相同的顺序,你可以简单地改变一下while条件。

只需implode() 搜索数组并使用strpos() 检查您可以使用array_slice() 获得并且还内爆为字符串的子数组是否在搜索数组中。

<?php

    $a = array("A", "B", "C", "F", "H", "K", "L", "M", "N", "R", "S", "X", "Y", "Z");
    $b = array("A", "B" , "C", "D", "E","F", "H", "M", "N", "R", "S", "F", "G", "H", "I", "M", "N", "R", "S");

    $length = count($a);
    $followUp = 0;
    for($i = 0; $i < $length; $i++) {

        echo $a[$i];
        $current = $i;
        while(isset($a[$i]) && strpos(implode("|", $b), implode("|", array_slice($a, $current, $followUp+1))) !== FALSE){
            ++$followUp;
            ++$i;
        }

        if($followUp > 2)
            echo "-" . $a[--$i];

        if($i != count($a) - 1)
            echo ",";

        if($followUp <= 2) $i = $current;
        $followUp = 0;

    }

?>

输出:

A-C,F,H,K,L,M-S,X,Y,Z

【讨论】:

  • 哇,你用 ord 打败了我。
  • 我也是不小心在JS里弄的,所以我的回答没用。
  • 我的问题的答案很棒。虽然我应该补充一点,数组中的值可以是任何值: ("b", "FF", "12", "a");所以它会为(“FF”,“12”,“a”)显示“FF-a”
  • @Cheppa 更新了我的答案。我想我现在知道你想要什么了。
  • @Rizier123 这很聪明。我需要很长时间才能考虑在 strpos 中使用 implode。非常感谢
【解决方案2】:

试试这个解决方案。它只有一个循环。

$a = array("A", "B", "C", "F", "H", "K", "L", "M", "N", "R", "S", "X", "Y", "AA", "AB", "AC", "AD");
$d = [];

$isFollow = false;

foreach($a as $el){
    if (count($d) == 0){
        $d[] = $el;
        continue;
    }

    $next = $d[count($d) - 1];
    $next++;

    if ($el == $next){
        $isFollow ? $d[count($d) - 1] = $el : $d[] = $el;
        $isFollow = true;
    } else {
        if ($isFollow){
            $d[count($d) - 2] .= "-".$d[count($d) - 1];
            $d[count($d) - 1] = $el;
        } else $d []= $el;

        $isFollow = false;
    }
}

if ($isFollow){
    $d[count($d) - 2] .= "-".$d[count($d) - 1];
    unset($d[count($d) - 1]);
}

echo implode(',', $d);

输出是

A-C, F, H, K-N, R-S, X-Y, AA-AD

您可以编写比较连续元素的方法

$next = $d[count($d) - 1];
$next++;
if ($el == $next)

【讨论】:

    猜你喜欢
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多