Php:把它变成一个递归函数

时间:2015-09-07 12:21:14

标签: php function design-patterns

我目前有两个班。

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;

    }

}

使用ElementMetaData

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

我希望得到&#34;相似之处&#34;在所有元素之间。根据一个数组i Predefine ...所以这将产生这个结果:

$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.

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

另外,我想添加更多&#34;标准&#34; ....所以"isEmailAdress", "beginswithA" ....等......这会让我的if语句变得恐怖......那么这里最好的战略/设计模式是什么?

2 个答案:

答案 0 :(得分:2)

@dezeze以公平的优势击败了我......但我仍然会发布我的解决方案基本上采用相同的原则。

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

答案 1 :(得分:1)

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

将每个标准实施为一个类:

>>> class MyMetaClass(type):
...     def __new__(cls, *args, **kwargs):
...         print('call __new__ from MyMetaClass.')
...         return type(*args, **kwargs)
... 
>>> class Foo(object):
...     __metaclass__ = MyMetaClass
... 
call __new__ from MyMetaClass.
>>> Foo
<class '__main__.Foo'>
>>> class MyMetaClass(type):
...     def __new__(cls, *args, **kwargs):
...         print('call __new__ from MyMetaClass.')
...         return type(cls.__name__, *args[1:], **kwargs)
... 
>>> class Foo(object):
...     __metaclass__ = MyMetaClass
... 
call __new__ from MyMetaClass.
>>> Foo
<class '__main__.MyMetaClass'>
>>> # Note the  ^^^^^^^^^^^^ class.__name__ attribute here
...

然后,您可以制作所有条件的数组:

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