【问题标题】:Search needle in_array using a user-defined comparison function使用用户定义的比较函数搜索 needle in_array
【发布时间】:2019-09-11 20:19:27
【问题描述】:

在搜索了一些关于这个问题的 SO 问题后,我只能找到 thisthis 但两者都不允许将参数(AKA needle)发送到搜索函数,而是使用预定义函数并使用 array_filter

我搜索了in_array documentation,但没有找到。

我想要类似的东西(如usort 启用):

function uin_array($haystack, $needle, $compareFunc)

我设法用简单的foreach 循环来实现它:

function uin_array($haystack, $needle, $compareFunc) {
    foreach($haystack as $e) {
        if ($compareFunc($needle, $e) == 0)
            return true;
    }    
    return false;
}

例子:

$found = uin_array(["AA", "BB", "CC", "DD"], "cc", "strcasecmp");

这也可以用于在多维数组中搜索。

我的问题

PHP 中是否有任何我不知道的内置函数/标志? 有没有更好的实现方式?

编辑

我知道我可以将array_filter 用作:current(array_filter($haystack, function($element) use ($needle) { ... })) 但在 所有 情况下是 O(n) - 在某些情况下使用循环和中断或 in_array 可能是 O(1) (仅在最坏的情况下为 O(n),但不是全部)

【问题讨论】:

  • array_filter?
  • 我知道我可以做类似current(array_filter($haystack, function($element) use ($needle) { ... })) 的事情,但在所有情况下都是O(n) - 使用循环和中断或in_array 在某些情况下可能是O(1)(将是O(n)仅在最坏的情况下,但不是全部)
  • 您在问题中提供的功能是最佳解决方案。核心 php 没有任何用户定义的in_array 变体。

标签: php arrays search


【解决方案1】:

如果你不怕函数柯里化,看看functional-php library

use function Functional\partial_any;
use function Functional\some;
use function Functional\placeholder;

$haystack = ["AA", "BB", "CC", "DD"];
$needle = "cc";
$compareFunc = "strcasecmp";

$found = some($haystack, partial_any($compareFunc, $needle, placeholder()));

这个库提供了很好的帮助来编写更多功能风格的代码,但我建议你在整个项目中使用它或者根本不使用它,因为只需要它一两次偶尔使用并不能使很有道理。

【讨论】:

  • 这也是一个不错的答案,赞成 - 但我正在搜索 PHP 核心功能(可能不存在) - 所以不完全是我想要的。谢谢!
【解决方案2】:

您可以使用array_mapstrcasecamparray_filter

$needle      = 'cc';
$compareFunc = 'strcasecmp';
$found    = count(array_filter(array_map(function($v) use ($needle,$compareFunc){
  if($compareFunc($v, $needle) == 0) return 1;
}, ["AA", "BB", "CC", "DD"])));

【讨论】:

  • 我知道,我有类似于问题中的示例(编辑部分)。我正在寻找更有效的解决方案。目前@AlexeyShokov 的答案是最好的,但我在等着看是否有人能想出一个更好的答案
  • @dWinder 您在这里谈论的是用户定义的比较,但在解决方案中,他使用 strcasecmp 作为静态?用户可以在哪里更改比较功能?
  • 我猜它可以用作:$found = \iter\any(function ($value) use ($needle, $compareFunc) { return $compareFunc($needle, $value); }, $haystack);
  • 我无法执行此操作,出现“致命错误:未捕获错误:调用未定义函数 iter\any()”
  • 我明白了,需要用到库
【解决方案3】:

看看一个很棒的nikic/iter library

$haystack = ["AA", "BB", "CC", "DD"];
$needle = "cc";

$found = \iter\any(function ($value) use ($needle) {
    return strcasecmp($needle, $value);
}, $haystack);

【讨论】:

  • 迄今为止的最佳答案。我建议将其编辑为 $found = \iter\any(function ($value) use ($needle, $compareFunc) { return $compareFunc($needle, $value); }, $haystack); 以便比较函数可以作为参数并添加 use iter\fn; 。赞成。我还在等着看是否会出现更好的答案,否则会接受。
  • 是的,如果您想灵活使用$compareFunc,请参阅我的第二个答案functional-php lib 示例
【解决方案4】:

为此,您可以使用 array_reduce 或 array_filter 返回 0、1 或更多符合您条件的项目。

【讨论】:

  • 这些函数将查看数组的所有元素。而OP已经提供的功能在找到所需的项目后会中断。
  • 我的建议背后的想法是确实遍历数组的所有元素。这样,如果您有多个匹配项,则可以找到所有匹配项。如果意图只是找到第一个匹配项,那么这些将不会很好。这个问题提出了一个合理的需求,即需要一个 PHP 扩展来做这件事,并且以后可以将其引入 PHP 核心。
猜你喜欢
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多