使用用户定义函数搜索 PHP 数组的优雅方式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14224812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Elegant way to search an PHP array using a user-defined function
提问by lethal-guitar
Basically, I want to be able to get the functionality of C++'s find_if(), Smalltalk's detect:etc.:
基本上,我希望能够获得 C++ find_if()、Smalltalkdetect:等的功能:
// would return the element or null
check_in_array($myArray, function($element) { return $elemnt->foo() > 10; });
But I don't know of any PHP function which does this. One "approximation" I came up with:
但我不知道有任何 PHP 函数可以做到这一点。我想出了一个“近似值”:
$check = array_filter($myArray, function($element) { ... });
if ($check)
//...
The downside of this is that the code's purpose is not immediately clear. Also, it won't stop iterating over the array even if the element was found, although this is more of a nitpick (if the data set is large enough to cause problems, linear search won't be an answer anyway)
这样做的缺点是代码的目的不是很明确。此外,即使找到了元素,它也不会停止遍历数组,尽管这更像是一个挑剔(如果数据集大到足以引起问题,则无论如何线性搜索都不是答案)
采纳答案by KingCrunch
You can write your own function ;)
您可以编写自己的函数;)
function callback_search ($array, $callback) { // name may vary
return array_filter($array, $callback);
}
This maybe seems useless, but it increases semantics and can increase readability
这可能看起来没用,但它增加了语义并可以增加可读性
回答by Izkata
To pull the first one from the array, or return false:
从数组中拉出第一个,或返回false:
current(array_filter($myArray, function($element) { ... }))
回答by Thank you
Here's a basic solution
这是一个基本的解决方案
function array_find($xs, $f) {
foreach ($xs as $x) {
if (call_user_func($f, $x) === true)
return $x;
}
return null;
}
array_find([1,2,3,4,5,6], function($x) { return $x > 4; }); // 5
array_find([1,2,3,4,5,6], function($x) { return $x > 10; }); // null
In the event $f($x)returns true, the loop short circuits and $xis immediately returned. Compared to array_filter, this is better for our use case because array_finddoes not have to continue iterating after the first positive match has been found.
在事件$f($x)返回时true,循环短路并$x立即返回。与 相比array_filter,这对我们的用例更好,因为array_find在找到第一个正匹配后不必继续迭代。
In the event the callback never returns true, a value of nullis returned.
如果回调从不返回 true,null则返回值。
Note, I used call_user_func($f, $x)instead of just calling $f($x). This is appropriate here because it allows you to use any compatible callable
注意,我使用call_user_func($f, $x)而不是仅仅调用$f($x). 这在这里很合适,因为它允许您使用任何兼容的可调用
Class Foo {
static private $data = 'z';
static public function match($x) {
return $x === self::$data;
}
}
array_find(['x', 'y', 'z', 1, 2, 3], ['Foo', 'match']); // 'z'
Of course it works for more complex data structures too
当然它也适用于更复杂的数据结构
$data = [
(object) ['id' => 1, 'value' => 'x'],
(object) ['id' => 2, 'value' => 'y'],
(object) ['id' => 3, 'value' => 'z']
];
array_find($data, function($x) { return $x->id === 3; });
// stdClass Object (
// [id] => 3
// [value] => z
// )
If you're using PHP 7, add some type hints
如果您使用的是 PHP 7,请添加一些类型提示
function array_find(array $xs, callable $f) { ...
回答by Roey
The original array_searchreturns the key of the matched value, and not the value itself (this might be useful if you're will to change the original array later).
原始array_search返回匹配值的键,而不是值本身(如果您以后要更改原始数组,这可能很有用)。
try this function (it also works will associatives arrays)
试试这个函数(它也适用于关联数组)
function array_search_func(array $arr, $func)
{
foreach ($arr as $key => $v)
if ($func($v))
return $key;
return false;
}
回答by Quolonel Questions
Use \iter\search()from nikic's iter libraryof primitive iteration functions. It has the added benefit that it operates on both arrays andTraversablecollections.
使用\iter\search()nikic 的原始迭代函数iter 库。它有一个额外的好处,它可以对数组和Traversable集合进行操作。
$foundItem = \iter\search(function ($item) {
return $item > 10;
}, range(1, 20));
if ($foundItem !== null) {
echo $foundItem; // 11
}
回答by GolezTrol
You can write such a function yourself, although it is little more than a loop.
您可以自己编写这样的函数,尽管它只不过是一个循环。
For instance, this function allows you to pass a callback function. The callback can either return 0 or a value. The callback I specify returns the integer if it is > 10. The function stops when the callback returns a non null value.
例如,此函数允许您传递回调函数。回调可以返回 0 或一个值。如果大于 10,我指定的回调将返回整数。当回调返回非空值时,该函数停止。
function check_in_array(array $array, $callback)
{
foreach($array as $item)
{
$value = call_user_func($callback, $item);
if ($value !== null)
return $value;
}
}
$a = array(1, 2, 3, 6, 9, 11, 15);
echo check_in_array($a, function($i){ return ($i > 10?$i:null); });

