如何在PHP中找到第一个大于X的数组元素?

9

我有一个包含数字值的数组,我想获取第一个值大于或等于5的元素的键。是否有比在foreach中循环所有元素更优雅的方法?

// "dirty" way
foreach ([0, 0, 4, 4, 5, 7] as $key => $value) {
    if ($value >= 5) {
        echo $key;
        break;
    }
}

1
为什么这是一种不规范的方式? - Rahil Wazir
那么,这个数组总是排序好的吗? - Ja͢ck
1
优雅的意思是如果存在内置的PHP函数可以更轻松地处理它...这个解决方案有效,但我更喜欢最佳解决方案而不是好的解决方案(如果这不是最佳解决方案)。 - Livia Martinez
2
在大型排序数组上,您可以使用二分搜索获得更好的性能;虽然这会增加更多的代码,但并不一定更优雅。 - Ja͢ck
1
如果数组已经排好序(在示例中看起来是这样的),您可以使用快速排序的方法——在每次迭代中检查中间值并丢弃一半……更加高效。 - Ross
显示剩余5条评论
2个回答

8

这个算法本身完全没问题,不需要修改。

但是,你可以通过编写一个通用的搜索函数来增加一些功能:

// find first key (from beginning of $a) for which the corresponding
// array element satisfies predicate $fn
function array_find(array $a, callable $fn)
{
    foreach ($a as $key => $value) {
        if ($fn($value, $key, $a)) {
            return $key;
        }
    }
    return false;
}

$key = array_find([0, 0, 4, 4, 5, 7], function($value) {
    return $value >= 5;
});

虽然这种方法更加优雅,但效率较低。在每个项目上调用闭包会带来相当大的开销。如果性能至关重要,请使用您已有的方法并继续使用。


-1

使用array_search()在寻找最早匹配时可能很有效,但在这种情况下不合适,因为它不允许您提供所需的搜索逻辑。

使用像array_map()array_filter()这样的函数迭代器并不理想,因为它们缺乏“短路”的能力,一旦匹配就会停止。在我的专业项目中,即使在相对较小的数据集上,我也不会使用函数式技术,因为这样做没有任何有价值的收益。

考虑到上述问题,只需使用一个经典的循环,并在其主体中设置条件以在符合条件的匹配项出现时终止循环。

$test变量在我的可运行演示链接的测试用例循环内定义。要试用下面的代码,请确保在进入循环之前将$test定义为您的搜索目标。

数组值大于或等于搜索目标的最早键名:(演示)

$array = [0, 0, 4, 4, 5, 7];

$foundKey = 'not found';
foreach ($array as $key => $value) {
    if ($value >= $test) {
        $foundKey = $key;
        break;
    }
}

获取不大于给定值的最高键: (演示)

$array = [0, 0, 4, 4, 5, 7];

$foundKey = 'not found';
foreach ($array as $key => $value) {
    if ($value > $test) {
        break;
    }
    $foundKey = $key;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接