为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PHP
慕盖茨4494581 2023-11-03 15:44:49
我需要 PHP 函数来比较两个数组中元素的顺序。第一个数组是标准数组,保存正确的顺序,第二个数组是要比较的数组。数组中要比较的元素可以重复。要比较的数组不能包含标准具数组中的所有元素。例子:<?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。谢谢。
查看完整描述

4 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

假设数组中不能有布尔值,您可以执行以下操作:


<?php

/**

 * @param string[] $standard

 * @param string[] $to_compare

 * @return bool

 */

function compare(array $standard, array $to_compare) : bool {

    $standard_item = reset($standard);


    foreach ($to_compare as $item) {

        // Skip standard items assuming they are all optional

        while ($item !== $standard_item) {

            $standard_item = next($standard);

            if ($standard_item === false) {

                return false;

            }

        }


        if ($standard_item === false || $item !== $standard_item) {

            return false;

        }

    }

    return true;

}

如果您想支持false标准数组中的值,可以修改上面的代码,以便通过索引引用项目,例如$standard[$i]。但这种方法也有其缺点——键必须是数字且连续的。对于更通用的解决方案,我可能会使用迭代器,例如ArrayIterator.


查看完整回答
反对 回复 2023-11-03
?
当年话下

TA贡献1890条经验 获得超9个赞

我发现一个可能的解决方案很容易遵循:


class Transition

{

    private string $fromValue;

    private array $toValues;


    public function __construct(string $fromValue, array $toValues)

    {

        $this->fromValue = $fromValue;

        $this->toValues = $toValues;

    }


    public function getFromValue(): string

    {

        return $this->fromValue;

    }


    public function getToValues(): array

    {

        return $this->toValues;

    }

}


function prepareTransitionsMap(array $orderDefinitions): array

{

    $transitions = [];

    $definitionsCount = count($orderDefinitions);

    foreach ($orderDefinitions as $i => $fromValue) {

        $toValues = [];

        for ($j = $i; $j < $definitionsCount; ++$j) {

            $toValues[] = $orderDefinitions[$j];

        }


        $transitions[$fromValue] = new Transition($fromValue, $toValues);

    }


    return $transitions;

}


function isArrayOrderValid(array $orderDefinitions, array $valuesToCheck): bool

{

    $valuesCount = count($valuesToCheck);

    if ($valuesCount === 0) {

        return true;

    }


    $definitionsCount = count($orderDefinitions);

    if ($definitionsCount === 0) {

        return false;

    }


    $transitionsMap = prepareTransitionsMap($orderDefinitions);

    foreach ($valuesToCheck as $i => $iValue) {

        $valueToCheck = $iValue;


        // value is no defined at all

        if (!array_key_exists($valueToCheck, $transitionsMap)) {

            return false;

        }


        // value is the last in the array

        if (!array_key_exists($i + 1, $valuesToCheck)) {

            return true;

        }


        $nextValue = $valuesToCheck[$i + 1];

        $transition = $transitionsMap[$valueToCheck];


        if (!in_array($nextValue, $transition->getToValues(), true)) {

            return false;

        }

    }


    return true;

}


isArrayOrderValid($standard, $valid_order); // true

isArrayOrderValid($standard, $invalid_order); // false


查看完整回答
反对 回复 2023-11-03
?
忽然笑

TA贡献1806条经验 获得超5个赞

你想使用usort() https://www.php.net/manual/fr/function.usort.php

它看起来像

function custom_sort(&$my_array) {

    return usort($my_array, function ($a, $b) {

        global $etalon;

        $a_key = array_search($a, $etalon);

        $b_key = array_search($b, $etalon);

        if (($a_key === FALSE) || ($b_key === FALSE) || ($a_key == $b_key)) {

            return 0;

        }

        ($a_key < $b_key) ? -1 : 1;

    });

}


custom_sort($valid_order);

custom_sort($invalid_order)


查看完整回答
反对 回复 2023-11-03
?
杨魅力

TA贡献1811条经验 获得超5个赞

另一个可以提供帮助的解决方案:


 // Etalon

    $etalon = 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'

    );

    


function checkOrder($array , $etalon)

{

    $array = array_values(array_unique($array));

    $array = array_intersect($array, $etalon );

    

    foreach($array as $key => $value){

        if(!in_array($array[$key],$etalon) || array_search($array[$key], $etalon)<$key){

          return false;

        }

    }

    return true;

}



var_dump(checkOrder($valid_order,$etalon)); // true


var_dump(checkOrder($invalid_order,$etalon)); // false


查看完整回答
反对 回复 2023-11-03
  • 4 回答
  • 0 关注
  • 82 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信