首页 > 解决方案 > 如果每个功能都被弃用了,如何恢复该功能提供的美感?

问题描述

直到找到的典型搜索算法,在 PHP 和一些我们不能使用语言数组搜索函数(我认为)的数组中,可以通过这种方式实现:

    $found = false;

    while (list($key, $alreadyRP) = each($this->relatedProducts) && !$found) {
        if ($alreadyRP->getProduct()->getId() === $rp->getProduct()->getId()) {
            $found = true;
        }
    }
    if (!$found) {
        // Do something here
    }

请把它当作伪代码,我没有执行它。我喜欢它的一点是,如果找到我们正在寻找的东西,它就会优雅地停止。

现在,由于不推荐使用“每个”函数,我必须编写如下代码:

    $found = false;
    foreach ($this->relatedProducts as $alreadyRP) {
        if ($alreadyRP->getProduct()->getId() === $rp->getProduct()->getId()) {
            $found = true;
            break;
        }
    }
    if (!$found) {
        // Do something here
    }

在结构化编程中将“break”语句放在“for”循环中是丑陋的。是的,它是可选的,但如果我们避免它,“foreach”将遍历所有数组,这不是最有效的方式。

有什么想法可以恢复“每个”在这种情况下给出的效率和结构吗?

谢谢你。

标签: php

解决方案


each()方法的美妙之处在于旁观者的眼中,但还有其他原因更喜欢 foreach,包括来自RFC 的这一有趣的信息,导致弃用each()

each() 函数在几乎所有可以想象的方式上都不如 foreach,包括慢 10 倍以上。

如果该方法的目的是 // Do something here如果在$rp中找不到$this->relatedProducts,我认为处理它的更“漂亮”的方法是将通过相关产品的搜索提取到一个单独的方法中。

protected function inRelatedProducts($id) {
    foreach ($this->relatedProducts as $alreadyRP) {
        if ($alreadyRP->getProduct()->getId() === $id) {
            return true;
        }
    }
    return false;
}

将相关产品搜索移动到单独的方法中是有利的,因为

  • 它将该功能与原始方法分开,使其变得可重用,而不是与所做的任何事情相关联// Do something here
  • 它简化了原始方法,因此可以专注于其主要任务

    $id = $rp->getProduct()->getId();
    if (!$this->inRelatedProducts($id)) {        
        // Do something here
    }
    
  • 它简化了搜索代码,因为如果它包含在自己的方法中,您就可以在return true;找到匹配项时立即进行,因此您根本不需要中断或跟踪$found变量。


另一方面,如果这是我的项目,我会寻找一种方法来消除对这种方法的需求,方法是填充$this->relatedProducts以便它由 ID 索引(假设 ID 在那里是唯一的),因此可以将确定减少到

$id = $rp->getProduct()->getId();
if (isset($this->relatedProducts[$id])) { ...

推荐阅读