Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/247.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php:将其转换为递归函数_Php_Function_Design Patterns - Fatal编程技术网

Php:将其转换为递归函数

Php:将其转换为递归函数,php,function,design-patterns,Php,Function,Design Patterns,我目前有两门课 ArrayCompare类: <?php namespace App\Tools\RegexExtract; class ArrayCompare { public function compare(Array $arrayToCompare) { $elementData = new ElementMetaData(); $metaData = $elementData->extract($arrayToCom

我目前有两门课

ArrayCompare
类:

<?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;

    }

}
基本功能是:

假设我有一个数组

$arr=[1,2,3];
我想得到所有元素之间的“相似性”。根据我预先定义的数组…这将产生以下结果:

$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.
现在我的解决方案不使用递归函数…但我相信它可以以某种方式使用


另外,我想添加更多的“标准”…所以
“IsemailAddress”,“beginswithA”
…等等…这会让我的if语句变得可怕…那么,在这里遵循的最佳策略/设计模式是什么呢?

我认为这里不需要递归,所以我只想提出一个设计方法的建议:

将每个标准作为一个类来实现:

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以相当大的优势击败了我。。。但我仍然会发布我的解决方案,它基本上使用相同的原则

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);

我在您的任务中看不到任何递归模式。当然,您可以将任何序列折叠编写为递归。问题是:你需要这个吗?很高兴听到这个。我认为还有改进/表现的余地。由于这些数组可能很长……但如果有更好的可读性方法,设计模式路径上的代码管理会很高兴听到它。我认为不需要单独的
ElementMetaData
类,因为它根本没有状态,只是以静态方式调用
extract
。它不应该是一个类,整个过程可能只在一个函数中实现,使用
if..elseif
case
来测试您的标准。特别是当性能是一个问题时。
$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);