比较两个数组中元素的顺序

我需要 PHP 函数来比较两个数组中元素的顺序。第一个数组是标准数组,保存正确的顺序,第二个数组是要比较的数组。

  1. 数组中要比较的元素可以重复。

  2. 要比较的数组不能包含标准具数组中的所有元素。

例子:

<?php

    // Standard

    $standard = array(

        'taxonomy',

        'post_meta',

        'author',

        'date',

        'post_meta_num'

    );

    

    // Valid order

    $valid_order = array(

        'taxonomy',

        'taxonomy',

        'post_meta',

        'date'

    );

    

    // Invalid order, 'author' is before 'post_meta'

    $invalid_order = array(

        'taxonomy',

        'author',

        'author',

        'post_meta'

    );

?>

我试图在 StackOverflow 上找到一些东西,但已有的答案与我的任务不兼容。仅当要比较的数组包含标准中的所有元素时,此函数才能正常工作。


<?php

    function compare( $standard, $to_compare  ){

        if( ! is_array( $standard ) || ! is_array( $to_compare ) ){

            return false;

        }

    

        $i = 0;

    

        foreach ( $to_compare as $value ) {

            if( $value === $standard[$i] ){

                $i++;

            }

        }

    

        return ( $i == count( $standard ) );

    }

?>

最后,如果要比较的标准和数组中的顺序相等,则该函数应返回 true;如果不相等,则该函数应返回 false。谢谢。


慕盖茨4494581
浏览 87回答 4
4回答

手掌心

假设数组中不能有布尔值,您可以执行以下操作:<?php/**&nbsp;* @param string[] $standard&nbsp;* @param string[] $to_compare&nbsp;* @return bool&nbsp;*/function compare(array $standard, array $to_compare) : bool {&nbsp; &nbsp; $standard_item = reset($standard);&nbsp; &nbsp; foreach ($to_compare as $item) {&nbsp; &nbsp; &nbsp; &nbsp; // Skip standard items assuming they are all optional&nbsp; &nbsp; &nbsp; &nbsp; while ($item !== $standard_item) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $standard_item = next($standard);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($standard_item === false) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if ($standard_item === false || $item !== $standard_item) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return true;}如果您想支持false标准数组中的值,可以修改上面的代码,以便通过索引引用项目,例如$standard[$i]。但这种方法也有其缺点——键必须是数字且连续的。对于更通用的解决方案,我可能会使用迭代器,例如ArrayIterator.

当年话下

我发现一个可能的解决方案很容易遵循:class Transition{&nbsp; &nbsp; private string $fromValue;&nbsp; &nbsp; private array $toValues;&nbsp; &nbsp; public function __construct(string $fromValue, array $toValues)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; $this->fromValue = $fromValue;&nbsp; &nbsp; &nbsp; &nbsp; $this->toValues = $toValues;&nbsp; &nbsp; }&nbsp; &nbsp; public function getFromValue(): string&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->fromValue;&nbsp; &nbsp; }&nbsp; &nbsp; public function getToValues(): array&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->toValues;&nbsp; &nbsp; }}function prepareTransitionsMap(array $orderDefinitions): array{&nbsp; &nbsp; $transitions = [];&nbsp; &nbsp; $definitionsCount = count($orderDefinitions);&nbsp; &nbsp; foreach ($orderDefinitions as $i => $fromValue) {&nbsp; &nbsp; &nbsp; &nbsp; $toValues = [];&nbsp; &nbsp; &nbsp; &nbsp; for ($j = $i; $j < $definitionsCount; ++$j) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $toValues[] = $orderDefinitions[$j];&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; $transitions[$fromValue] = new Transition($fromValue, $toValues);&nbsp; &nbsp; }&nbsp; &nbsp; return $transitions;}function isArrayOrderValid(array $orderDefinitions, array $valuesToCheck): bool{&nbsp; &nbsp; $valuesCount = count($valuesToCheck);&nbsp; &nbsp; if ($valuesCount === 0) {&nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; }&nbsp; &nbsp; $definitionsCount = count($orderDefinitions);&nbsp; &nbsp; if ($definitionsCount === 0) {&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }&nbsp; &nbsp; $transitionsMap = prepareTransitionsMap($orderDefinitions);&nbsp; &nbsp; foreach ($valuesToCheck as $i => $iValue) {&nbsp; &nbsp; &nbsp; &nbsp; $valueToCheck = $iValue;&nbsp; &nbsp; &nbsp; &nbsp; // value is no defined at all&nbsp; &nbsp; &nbsp; &nbsp; if (!array_key_exists($valueToCheck, $transitionsMap)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // value is the last in the array&nbsp; &nbsp; &nbsp; &nbsp; if (!array_key_exists($i + 1, $valuesToCheck)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; $nextValue = $valuesToCheck[$i + 1];&nbsp; &nbsp; &nbsp; &nbsp; $transition = $transitionsMap[$valueToCheck];&nbsp; &nbsp; &nbsp; &nbsp; if (!in_array($nextValue, $transition->getToValues(), true)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return true;}isArrayOrderValid($standard, $valid_order); // trueisArrayOrderValid($standard, $invalid_order); // false

忽然笑

你想使用usort()&nbsp;https://www.php.net/manual/fr/function.usort.php它看起来像function custom_sort(&$my_array) {&nbsp; &nbsp; return usort($my_array, function ($a, $b) {&nbsp; &nbsp; &nbsp; &nbsp; global $etalon;&nbsp; &nbsp; &nbsp; &nbsp; $a_key = array_search($a, $etalon);&nbsp; &nbsp; &nbsp; &nbsp; $b_key = array_search($b, $etalon);&nbsp; &nbsp; &nbsp; &nbsp; if (($a_key === FALSE) || ($b_key === FALSE) || ($a_key == $b_key)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; ($a_key < $b_key) ? -1 : 1;&nbsp; &nbsp; });}custom_sort($valid_order);custom_sort($invalid_order)

杨魅力

另一个可以提供帮助的解决方案:&nbsp;// Etalon&nbsp; &nbsp; $etalon = array(&nbsp; &nbsp; &nbsp; &nbsp; 'taxonomy',&nbsp; &nbsp; &nbsp; &nbsp; 'post_meta',&nbsp; &nbsp; &nbsp; &nbsp; 'author',&nbsp; &nbsp; &nbsp; &nbsp; 'date',&nbsp; &nbsp; &nbsp; &nbsp; 'post_meta_num'&nbsp; &nbsp; );&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // Valid order&nbsp; &nbsp; $valid_order = array(&nbsp; &nbsp; &nbsp; &nbsp; 'taxonomy',&nbsp; &nbsp; &nbsp; &nbsp; 'taxonomy',&nbsp; &nbsp; &nbsp; &nbsp; 'post_meta',&nbsp; &nbsp; &nbsp; &nbsp; 'date'&nbsp; &nbsp; );&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // Invalid order, 'author' is before 'post_meta'&nbsp; &nbsp; $invalid_order = array(&nbsp; &nbsp; &nbsp; &nbsp; 'taxonomy',&nbsp; &nbsp; &nbsp; &nbsp; 'author',&nbsp; &nbsp; &nbsp; &nbsp; 'author',&nbsp; &nbsp; &nbsp; &nbsp; 'post_meta'&nbsp; &nbsp; );&nbsp; &nbsp;&nbsp;function checkOrder($array , $etalon){&nbsp; &nbsp; $array = array_values(array_unique($array));&nbsp; &nbsp; $array = array_intersect($array, $etalon );&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; foreach($array as $key => $value){&nbsp; &nbsp; &nbsp; &nbsp; if(!in_array($array[$key],$etalon) || array_search($array[$key], $etalon)<$key){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return true;}var_dump(checkOrder($valid_order,$etalon)); // truevar_dump(checkOrder($invalid_order,$etalon)); // false
打开App,查看更多内容
随时随地看视频慕课网APP