首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在集合中查找对象实例的有效方法

在集合中查找对象实例的有效方法
EN

Code Review用户
提问于 2019-01-25 17:39:53
回答 2查看 107关注 0票数 3

我试图确定一个对象的实例是否存在于一个集合中。

我使用array_walk_recursive来遍历和检查数组的叶子。

我增加了一个小短路,但是所有的叶子都会被迭代。

另外,我也可以使用一些异常,比如在第一次发现时抛出的异常,提前爆发,但这感觉有点不对。

我错过了一个简单的选择吗?

代码语言:javascript
复制
 [new Whale, new Shark],
    'atlantic' => [new Human, new Shark]
];

$pub = [new Human, new Human];

var_dump(anyFish($seas));
var_dump(anyFish($pub));

输出:

代码语言:javascript
复制
bool(true)
bool(false)

在堆栈溢出:https://stackoverflow.com/questions/17853113/break-array-walk-from-anonymous-function上找到)

EN

回答 2

Code Review用户

回答已采纳

发布于 2019-01-27 22:13:44

我认为良好的编码实践应该在代码简洁之前优先考虑效率。重要的是不要要求做不必要的工作(这是作为一个聪明的编码器的艺术性的一部分)。在我看来,实现早期退出是选择“最佳”代码设计的一个不可商量的因素。

使用像array_walk_recursive()这样的函数来遍历叶节点是很方便的,但我也同意,提前退出的语法有点难看。因此,我建议使用语言构造作为递归设计的一部分。条件逻辑是唯一可以压缩的部分,所以我尽量把它压缩下来。

代码:(演示)

代码语言:javascript
复制
function anyFish(array $collection)
{
    foreach ($collection as $item)
    {
        if((is_array($item) && anyFish($item)) || $item instanceof Fish)
        {
            return true;
        }
    }
    return false;
}

我不认为这是可怕的,但每个人都爱自己的孩子。我不确定我能不能让它更易读。

票数 3
EN

Code Review用户

发布于 2019-01-27 22:00:22

下面是一个使用递归的例子,它在找到实例后很快就停止了,所以不会迭代整个集合。

代码语言:javascript
复制
 [new Whale, new Whale, new Shark, new Whale],
    'atlantic' => [new Human, new Shark]
];

$pub = [new Human, new Human];

var_dump(anyFish($seas));
var_dump(anyFish($pub));

输出:

代码语言:javascript
复制
bool(true)
bool(false)

@mickmackusa完美地提取了递归函数。

我在这里加入我的通用解决方案:

代码语言:javascript
复制
function hasInstance(array $collection, $class)
{
    foreach($collection as $item)
        if(is_array($item) && hasInstance($item, $class) || $item instanceof $class)
            return true;

    return false;
}

打个电话就像:

代码语言:javascript
复制
hasInstance($seas, Fish::class);
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/212229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档