6

Say I have an array with the following members:

car_porsche
car_mercedes
car_toyota
motorcycle_suzuki
motorcycle_honda
motorcycle_motoguzzi

How can I get an array with all the elements starting with car_? There was a native function for this but I forgot its name.

Do you know which function I mean? I know how to do it with for/foreach/array_filter. I'm quite sure there was a function for exactly this.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Pekka
  • 442,112
  • 142
  • 972
  • 1,088

6 Answers6

7

Well, you could do it using preg_grep():

$output = preg_grep('!^car_!', $array);

You could use array_filter() too but you have to pass a test function into that.

cletus
  • 616,129
  • 168
  • 910
  • 942
2

Regexp takes much more time to process, it`s better to use strpos() in this case:

foreach($arr AS $key => $val)
if(strpos(" ".$val, "car_") == 1)     
    $cars[$key] = $val;

This also works with keys:

Geek Num 88
  • 5,264
  • 2
  • 22
  • 35
InVeX
  • 21
  • 1
1

You can write a simple routine which gives you the option of dropping the prefix in your returned array:

function filter_by_key_prefix ( $arr, $prefix, $drop_prefix=false ) {
        $params = array();
        foreach( $arr as $k=>$v ) {
            if ( strpos( $k, $prefix ) === 0 ) {
                if ( $drop_prefix ) {
                    $k = substr( $k, strlen( $prefix ) );
                }
                $params[ $k ] = $v;
            }
        }
        return $params;
    }
Pete B
  • 1,709
  • 18
  • 11
0

PHP 8 (2021):

I’m using str_starts_with for this purpose.

Performs a case-sensitive check indicating if haystack begins with needle.

→ Documentation

str_starts_with("car_porsche", "car_");
ixany
  • 5,433
  • 9
  • 41
  • 65
0

Assuming that the search needle is a user-supplied value, before using it in a regular expression, it should be passed through preg_quote() to ensure that any characters with special meaning are escaped.

Using a preg_ function offers the deepest tooling such as case-insensitivity, multibyte parsing, and word boundaries ...if desirable.

Reversing the filtration with preg_grep() is simply done with a function flag. To reverse the filtration with non-regex functions, just invert the return value or the comparison on the return value (depending on which technique you use.

Codes (Demo)

function keepIfStartsWith_regex($haystack, $needle) {
    return preg_grep('/^' . preg_quote($needle, '/') . '/', $haystack);
}

function removeIfStartsWith_regex($haystack, $needle) {
    return preg_grep('/^' . preg_quote($needle, '/') . '/', $haystack, PREG_GREP_INVERT);
}

For case-sensitive matching the leading characters of a string in PHP8, use iterated calls of the concise and intuitive str_starts_with() function.

function keepIfStartsWith_PHP8($haystack, $needle) {
    return array_filter($haystack, fn($v) => str_starts_with($v, $needle));
}

function removeIfStartsWith_PHP8($haystack, $needle) {
    return array_filter($haystack, fn($v) => !str_starts_with($v, $needle));
}

For PHP versions under 8, you can make iterated calls of strpos() for case-sensitive or stripos() for case-insensitive matching. You must explicitly check if the return value is identical to 0 because performing a loose comparison (type-juggled comparison) will mistake 0 for false when no match is found.

function keepIfStartsWith_PHP7_4($haystack, $needle) {
    return array_filter($haystack, fn($v) => strpos($v, $needle) === 0);
}

function removeIfStartsWith_PHP7_4($haystack, $needle) {
    return array_filter($haystack, fn($v) => strpos($v, $needle) !== 0);
}

function keepIfStartsWith_sub7_4($haystack, $needle) {
    return array_filter($haystack, function($v) use($needle) { return strpos($v, $needle) === 0; });
}

function removeIfStartsWith_sub7_4($haystack, $needle) {
    return array_filter($haystack, function($v) use($needle) { return strpos($v, $needle) !== 0; });
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
-1

I think you can use array_filter() for that purpose.

casraf
  • 21,085
  • 9
  • 56
  • 91