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