【问题标题】:Remove all elements from array that do not start with a certain string从数组中删除所有不以某个字符串开头的元素
【发布时间】:2011-06-26 03:22:02
【问题描述】:

我有一个如下所示的数组:

array(
  'abc' => 0,
  'foo-bcd' => 1,
  'foo-def' => 1,
  'foo-xyz' => 0,
  // ...
)

如何只保留以foo- 开头的元素?

【问题讨论】:

  • 有一个带有这样前缀的数组是一种代码味道。将这些值提取到包含这些值的对象中,或者至少使前缀指向一个数组并将值添加到其中。

标签: php arrays key filtering array-filter


【解决方案1】:
foreach($arr as $key => $value)
{
   if(preg_match('/^foo-/', $key))
   {
        // You can access $value or create a new array based off these values
   }
}

【讨论】:

  • 在这种情况下,正则表达式并不是必需的。 substr 方法效率稍高
  • @jfoucher:确实如此,但就个人而言,它更容易阅读。
  • 它可能更灵活,但如果您不想想要进行正则表达式匹配,则需要转义特殊的 preg 字符。所以谨慎使用。我建议您仅在需要 RE 时才使用 RE。
【解决方案2】:

这就是我的做法,尽管在了解你想用你获得的价值做什么之前,我无法给你更有效的建议。

$search = "foo-";
$search_length = strlen($search);
foreach ($array as $key => $value) {
    if (substr($key, 0, $search_length) == $search) {
        ...use the $value...
    }
}

【讨论】:

  • 您也可以使用:foreach ($array as $key => $value) { if (0 === strpos($key, 'foo-')) { ...use the $value... } }
  • 这里的“4”需要调整成任何长度“foo-”。
【解决方案3】:

功能方法:

$array = array_filter($array, function($key) {
    return strpos($key, 'foo-') === 0;
}, ARRAY_FILTER_USE_KEY);

程序方法:

$only_foo = array();
foreach ($array as $key => $value) {
    if (strpos($key, 'foo-') === 0) {
        $only_foo[$key] = $value;
    }
}

使用对象的程序方法:

$i = new ArrayIterator($array);
$only_foo = array();
while ($i->valid()) {
    if (strpos($i->key(), 'foo-') === 0) {
        $only_foo[$i->key()] = $i->current();
    }
    $i->next();
}

【讨论】:

  • 注意 PHP 5.6 将 ARRAY_FILTER_USE_KEY 标志添加到 array_filter(),您可以使用它来代替提供自定义 array_filter_key() 函数。
  • 您能否将 array_filter_key 函数添加到您的示例中?我不断收到错误消息,不得不多次重新阅读您的帖子,然后才意识到我的错误。发布代码、节省点击并节省故障排除时间并不难。谢谢。
  • 这个答案会愚弄很多研究人员并浪费他们的时间,直到他们意识到array_filter_key() 不是本机函数。研究人员不必为了获得完整的解决方案而进行链接追踪。
【解决方案4】:
$arr_main_array = array('foo-test' => 123, 'other-test' => 456, 'foo-result' => 789);

foreach($arr_main_array as $key => $value){
    $exp_key = explode('-', $key);
    if($exp_key[0] == 'foo'){
         $arr_result[] = $value;
    }
}

if(isset($arr_result)){
    print_r($arr_result);
}

【讨论】:

  • 在你采取这个解决方案之前,下面的一个更好。永远不要在简单的字符串函数就足够的情况下使用数组函数。字符串函数要快得多。这将“滞后”于大型数组。
  • 我没有看到将数组键分解为数组的意义。它们是字符串,最初的问题只是询问字符串前缀。 OP 也要求“元素”而不仅仅是值,因此数字索引的结果将毫无用处 - 键在这里显然很重要,值是(可能)匿名 1/0 标志。
【解决方案5】:

从 PHP 5.3 开始,您可以使用 preg_filter 函数:here

$unprefixed_keys = preg_filter('/^foo-(.*)/', '$1', array_keys( $arr ));

// Result:
// $unprefixed_keys === array('bcd','def','xyz')

【讨论】:

    【解决方案6】:

    修改 erisco 的功能方法,

    array_filter($signatureData[0]["foo-"], function($k) {
        return strpos($k, 'foo-abc') === 0;
    }, ARRAY_FILTER_USE_KEY);
    

    这对我有用。

    【讨论】:

    • 与@erisco 提供的array_filter_key 版本相比,在性能或实用性上有什么不同吗?
    • 不。我猜性能应该没有任何差异。 @MaciekSemik
    • 这是一个核心的 PHP 函数,所以应该首选它。
    【解决方案7】:

    我只是使用array_filter函数实现了如下解决方案

    <?php
    
    $input = array(
        'abc' => 0,
        'foo-bcd' => 1,
        'foo-def' => 1,
        'foo-xyz' => 0,
    );
    
    $filtered = array_filter($input, function ($key) {
        return strpos($key, 'foo-') === 0;
    }, ARRAY_FILTER_USE_KEY);
    
    print_r($filtered);
    

    输出

    Array
    (
        [foo-bcd] => 1
        [foo-def] => 1
        [foo-xyz] => 0
    )
    

    实时检查https://3v4l.org/lJCse

    【讨论】:

    • 请注意,这至少需要 PHP 5.6.0(由于使用了常量 ARRAY_FILTER_USE_KEY)。在以前的版本中,您可以使用:[code]
    【解决方案8】:

    除了@Suresh Velusamy 的上述回答(至少需要 PHP 5.6.0)之外,如果您使用的是 PHP 的早期版本,您还可以使用以下内容:

    <?php
    
    $input = array(
        'abc' => 0,
        'foo-bcd' => 1,
        'foo-def' => 1,
        'foo-xyz' => 0,
    );
    
    $filtered = array_filter(array_keys($input), function($key) {
        return strpos($key, 'foo-') === 0;
    });
    
    print_r($filtered);
    
    /* Output:
    Array
    (
        [1] => foo-bcd
        [2] => foo-def
        [3] => foo-xyz
    )
    // the numerical array keys are the position in the original array!
    */
    
    // if you want your array newly numbered just add:
    $filtered = array_values($filtered);
    
    print_r($filtered);
    
    /* Output:
    Array
    (
        [0] => foo-bcd
        [1] => foo-def
        [2] => foo-xyz
    )
    */
    

    【讨论】:

    • 请注意(或至少对我而言)这只会返回匹配的数组键。 @suresh-velusamy 下面的答案使用原始 $key =&gt; $value 对提取实际数组。此答案的输出中已说明,但尚未明确提及
    【解决方案9】:

    从 PHP5.6 开始,可以使用 ARRAY_FILTER_USE_KEY 常量/标志来过滤数组键。

    从 PHP7.4 开始,arrow functions 使自定义函数更加简洁,并允许在没有use() 的情况下将值传递到自定义函数的作用域中。

    从 PHP8 开始,str_starts_with() 可以代替 strpos(...) === 0

    代码:(Demo)

    $array = [
      'abc' => 0,
      'foo-bcd' => 1,
      'foo-def' => 1,
      'foo-xyz' => 0,
    ];
    
    $prefix = 'foo';
    
    var_export(
        array_filter(
            $array,
            fn($key) => str_starts_with($key, $prefix),
            ARRAY_FILTER_USE_KEY
        )
    );
    

    输出:

    array (
      'foo-bcd' => 1,
      'foo-def' => 1,
      'foo-xyz' => 0,
    )
    

    【讨论】:

      猜你喜欢
      • 2010-09-08
      • 2021-02-12
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      相关资源
      最近更新 更多