Php: 将其转化为递归函数

Php: turning it into a recursive function

我目前有两个 class。

ArrayCompare class:

<?php
namespace App\Tools\RegexExtract;

class ArrayCompare
{


    public function compare(Array $arrayToCompare)
    {

        $elementData = new ElementMetaData();
        $metaData = $elementData->extract($arrayToCompare[0], [], $initial=true);

        foreach ($arrayToCompare as $currentElement) {

            $metaData = $elementData->extract($currentElement, $metaData);

        }

        return $metaData;

    }

}

它使用 ElementMetaData class

    <?php
/**
 * A class for extracting meta data from an element.
*/

namespace App\Tools\RegexExtract;

class ElementMetaData
{

    public function extract($element, $metaDataToCompare = [], $initial = false)
    {

        if ($initial == true) {
            $this->isInteger($element) ? $returnMetaData['isInteger'] = $this->isInteger($element) : null;
            $returnMetaData['length'] = $this->length($element);
        }

        else {

            $returnMetaData=$metaDataToCompare;


        if ($returnMetaData != []) {
            if (isset ($returnMetaData['isInteger']) && !$this->isInteger($element)) {
                unset($returnMetaData['isInteger']);

            }
            if (isset ($returnMetaData['length']) && $this->length($element) != $returnMetaData['length']) {
                unset($returnMetaData['length']);

            }

        }
        }

        return $returnMetaData;


    }

    private function isInteger($element)
    {
        return is_int($element);
    }

private function length($element)
{
    return strlen($element);

}

}

基本功能是:

假设我有一个数组

$arr=[1,2,3];

我想在 ALL 元素之间获取 "similarities"。根据我预定义的数组...所以这将提供以下结果:

$metaArray=['isInteger'=>true,'length'=>1];

这将提供与相似度一样的长度:

$arr=[1,2,'D'];
$metaArray=['length'=>1];

虽然此数组将提供一个空结果 []

$arr=[1,2,'3D']; // result is [] since not all integers or not all of same length.

现在我的解决方案不使用递归函数...但我相信它可以以某种方式使用。

此外,我想添加更多 "criteria".....所以 "isEmailAdress", "beginswithA".....等....这会使我的 if 语句变得恐怖....所以最好的 strategy/design 模式是什么?

我认为这里没有递归的必要,所以我只是提出一个设计方法的建议:

将每个标准实施为 class:

abstract class Criterion {

    protected $valid = true;

    abstract public function initialize($value);
    abstract public function check($value);

    public function isValid() {
        return $this->valid;
    }

}

class Length extends Criterion {

    protected $length;

    public function initialize($value) {
        $this->length = strlen($value);
    }

    public function check($value) {
        if ($this->length != strlen($value)) {
            $this->valid = false;
        }
    }

}

然后您将所有条件组成一个数组:

$criteria = [new Length, ...];
foreach ($criteria as $criterion) {
    $criterion->initialize($values[0]);
}

然后通过您的价值观慢慢削减它们:

foreach ($values as $value) {
    foreach ($criteria as $criterion) {
        $criterion->check($value);
    }
}

$commonCriteria = array_filter($criteria, function (Criterion $criterion) {
    return $criterion->isValid();
});

@deceze 以相当的优势击败了我...但我仍然post 我的解决方案基本上遵循相同的原则。

abstract class abstractComparer
{
    private $array;
    private $result = true;
    protected $name;

    public function compareArray($array)
    {
        $current = null;

        foreach ($array as $index => $value)
        {
            $this->result = $this->result && $this->compareValues($index, $current, $value);
            $current = $value;
        }
    }

    public function getResult()
    {
        return $this->result;
    }    

    public function getName()
    {
        return $this->name;
    }

    public abstract function compareValues($index, $value1, $value2);

    public abstract function getSuccessValue();
}

class intComparer extends abstractComparer
{
    protected $name = "isInteger";

    public function compareValues($index, $value1, $value2)
    {
        return is_int($value2);
    }

    public function getSuccessValue()
    {
        return true;
    }
}

class lengthComparer extends abstractComparer
{
    protected $name   = "length";
    protected $length = 0;

    public function compareValues($index, $value1, $value2)
    {
        $this->length = strlen($value2);
        return $index == 0 || strlen($value1) == $this->length;
    }

    public function getSuccessValue()
    {
        return $this->length;
    }
}

然后像这样进行实际处理:

$temp = [1,2,3];

$comparers = [new intComparer(), new lengthComparer()];
$result = array();

foreach ($comparers as $comparer)
{
    $comparer->compareArray($temp);

    if ($comparer->getResult())
    {
        $result[$comparer->getName()] = $comparer->getSuccessValue();
    }
}

//var_dump($result);