【问题标题】:First element of array by condition [duplicate]按条件排列的数组的第一个元素[重复]
【发布时间】:2019-01-18 13:22:50
【问题描述】:

我正在寻找一种优雅的方式来获取满足给定条件的数组的第一个(也是唯一一个)元素。

简单示例:

输入:

[
    ['value' => 100, 'tag' => 'a'],
    ['value' => 200, 'tag' => 'b'],
    ['value' => 300, 'tag' => 'a'], 
 ]

条件:$element['value'] > 199

预期输出:

['value' => 200, 'tag' => 'b']

我自己想出了几个解决方案:

  1. 遍历数组,检查条件并在找到时中断

  2. 使用 array_filter 应用条件并获取过滤后的第一个值:

    array_values(
        array_filter(
            $input, 
            function($e){
                return $e['value'] >= 200;
            }
        )
    )[0];
    

两者似乎都有点麻烦。有没有人有更清洁的解决方案?我是否缺少内置的 php 函数?

【问题讨论】:

  • 你能解释一下吗?
  • “遍历数组,检查条件并在找到时中断”是最干净、最快的解决方案。

标签: php array-filter


【解决方案1】:

我能找到的最短的是使用current

current(array_filter($input, function($e) {...}));

current 本质上是获取第一个元素,如果为空则返回false

如果代码经常重复,最好将其提取到自己的函数中。

【讨论】:

  • 谢谢!使用current 肯定比使用array_values 更好更快
  • 请注意它没有优化:array_filter 将对数组的每个元素执行您的函数,其中包括“获胜者”的所有后继元素。它可能很重要(如果您的数组有数千个值)或不重要(如果它只有 3 个)。
  • 这个解决方案适用于少量项目,但对于大数组,它非常慢......
【解决方案2】:

不需要使用上述所有功能,例如array_filter。因为array_filter filters 数组。而过滤查找第一个值不同。所以,只需这样做:

foreach ($array as $key => $value) {
    if (meetsCondition($value)) {
        $result = $value;
        break;
        // or: return $value; if in function
    }
}

array_filter 将过滤 整个 数组。因此,如果您需要的值是第一个,并且数组有 100 个或更多元素,array_filter 仍将检查所有这些元素。那么,你真的需要 100 次迭代而不是 1 次吗?答案很明确 -

【讨论】:

    【解决方案3】:

    你的数组:

    $array = [
    ['value' => 100, 'tag' => 'a'],
    ['value' => 200, 'tag' => 'b'],
    ['value' => 300, 'tag' => 'a'], 
    ];
    

    要通过条件查找条目,您可以这样做

    $newArray = array_values(array_filter($array, function($n){ return $n['value'] >= 101 && $n['value'] <= 400; }));
    

    有了这个,您可以设置值、最小值和最大值。

    如果你只想设置一个最小值,你可以像这样省略最大值

    $arrayByOnlyMin = array_values(array_filter($array, function($n){ return $n['value'] >= 199; }));
    

    这将返回:

     array(2) {
     [0]=>
        array(2) {
          ["value"]=>
          int(200)
          ["tag"]=>
          string(1) "b"
        }
     [1]=>
       array(2) {
          ["value"]=>
          int(300)
          ["tag"]=>
          string(1) "a"
        }
    }
    

    所以调用 $arrayByOnlyMin[0] 会给你第一个符合你的最低条件的条目。

    【讨论】:

    • aaand,我刚刚注意到,这与您所做的基本上完全相同:-D - 所以基本上..您做对了
    • 如果我们只看输入和输出,这个方法在技术上确实是正确的。但是,这绝对没有效率。在这里使用array_filter 并不是最好的选择。 array_filter 将在返回它的输出之前遍历完整的输入数组,这不是我们想要的。我们只想返回与谓词匹配的第一个项目。仅当 PHP 具有延迟执行时,您才可以使用 filter,但事实并非如此。如果您正在寻找惰性过滤器操作,可以查看我在这里构建的库:github.com/loophp/collection
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 2016-03-17
    • 2018-03-26
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多