【问题标题】:PHP: simplify with algorithm?PHP:用算法简化?
【发布时间】:2011-03-03 22:05:55
【问题描述】:
这是一段我认为不是很“漂亮”的 PHP 代码,我确信可以使用 for 或其他东西来简化它。我正在尝试找到可以解决此问题的算法,但我无法弄清楚,请帮助我。
代码如下:
if(isset($4))
{
if(isset($navi[$one][$two][$three][$four])) echo "/content/" 。一美元。 “/”。两美元。 “/”。三美元。 "/" .$4 . ".php";
否则回显“错误”;
}
否则 if(isset($3))
{
if(isset($navi[$one][$two][$three])) echo "/content/" 。一美元。 “/”。两美元。 “/”。三美元。 ".php";
否则回显“错误”;
}
否则 if(isset($2))
{
if(isset($navi[$one][$two])) echo "/content/" 。一美元。 “/”。两美元。 ".php";
否则回显“错误”;
}
否则 if(isset($one))
{
if(isset($navi[$one]))echo "/content/" 。一美元。 ".php";
否则回显“错误”;
}
别的
{
回声“错误”;
}
谢谢!
【问题讨论】:
标签:
php
algorithm
for-loop
simplify
【解决方案1】:
更新、测试:
$parts = array($one, $two, $three, $four);
$reversed = array_reverse($parts);
function getPath($ret, $n) {
global $parts;
foreach (range(0, $n) as $i) {
$ret = $ret[$parts[$i]];
}
return $ret;
}
$error = false;
foreach (range(0, count($reversed)) as $i) {
if (!$reversed[$i]) {
unset($reversed[$i]);
continue;
}
if (!getPath($navi, count($parts) - $i - 1)) {
$error = true;
break;
}
}
if ($error) {
echo "error!";
} else {
echo "/content/" . implode("/", array_reverse($reversed)) . ".php";
}
【解决方案2】:
问题是您使用的是isset(foo),这使得将变量放入数组变得很困难。如果可以测试变量的长度,则使用:
$parts = array_reverse(array($one,$two,$three,$four));
foreach ($parts as $i => $value)
if(strlen($value)==0)
unset($array[$i]);
$final = join('/',parts);
if(isset($navi[$final])) echo "/content/" . $final . ".php";
else echo "\nerror\n\n\n";
但这需要你改变你的 $navi 结构,使其看起来像
$navi['foo/bar/baz'] = "someval";
而不是
$navi['foo']['bar']['baz'] = "someval";
因为我们将使用连接的字符串$final 在$isset 中查找。否则唯一的路由是动态生成的 php,这太可怕了。
您能否以不同的方式构建数据?数组维度的循环并不好,而上面的平面列表更容易完成。
【解决方案3】:
我认为您的代码存在更深层次的问题。但是要解决这个问题——我的猜测是:
$urls = array();
$tempNavi = $navi;
foreach (array('one', 'two', 'three', 'four') as $var) {
if (!isset($$var) || !isset($tempNavi[$$var]))
break;
$tempNavi = $tempNavi[$$var];
$urls[] = $$var;
}
if ($urls) {
echo '/content/' . implode('/', $urls);
} else {
echo 'error';
}
【解决方案4】:
为了完整起见,递归解决方案:
function navi_recurse(&$navi, &$steps, $i = 0) {
if ($i < count($steps) - 1) {
$step = $steps[$i];
if ( isset($navi[$step]) )
return navi_recurse($navi[$step], $steps, $i+1);
else
return "error\n";
}
return '/content/'.implode('/', $steps).'.php';
}
这样调用:
$steps = array($one, $two, $three, $four);
echo navi_recurse($navi, $steps);