95

I have an array that looks like this:

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

How can I retain only the elements that start with foo-?

2
  • 3
    Having an array with prefixes like this is a code smell. Extract those values into an object holding these values or at least make the prefix point to an array and add the values to it. Commented Feb 12, 2011 at 17:29
  • See also: stackoverflow.com/questions/13766898/… Commented Oct 15, 2019 at 4:03

10 Answers 10

153

Functional approach:

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

Procedural approach:

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

Procedural approach using objects:

$i = new ArrayIterator($array);
$only_foo = array();
while ($i->valid()) {
    if (strpos($i->key(), 'foo-') === 0) {
        $only_foo[$i->key()] = $i->current();
    }
    $i->next();
}
Sign up to request clarification or add additional context in comments.

4 Comments

Note PHP 5.6 adds the ARRAY_FILTER_USE_KEY flag to array_filter(), which you can use instead of supplying a custom array_filter_key() function.
Can you please just add the array_filter_key function to your example? I kept getting an error and had to re-read your post multiple times before recognizing my mistake. It's not hard to just post the code, save a click, and save somebody time troubleshooting. Thanks.
This answer will be fooling a lot of researchers and wasting their time until they realize that array_filter_key() is not a native function. Researchers shouldn't have to link-chase to receive the whole solution.
With php8 you can also use str_starts_with($key, 'foo-')
38

This is how I would do it, though I can't give you a more efficient advice before understanding what you want to do with the values you get.

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

2 Comments

You also can use: foreach ($array as $key => $value) { if (0 === strpos($key, 'foo-')) { ...use the $value... } }
The "4" here needs to be adjusted to whatever length "foo-" is.
26

Simply I used array_filter function to achieve the solution as like follows

<?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);

Output

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

For live check https://3v4l.org/lJCse

1 Comment

Pay attention that this needs at least PHP 5.6.0 (due to the use of the constant ARRAY_FILTER_USE_KEY). In prior versions you can use: [code]
20

From PHP 5.3 you can use the preg_filter function: here

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

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

Comments

19
$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);
}

2 Comments

Before you take this solution, the one below is better. Never use array functions where simple string function will suffice. String functions are WAY faster. This will 'lag' with large arrays.
I don't see the point of exploding the array keys into arrays. They are strings and the original question is just asking about a string prefix. Also OP is asking for "the elements" rather than just the values, so the numerically-indexed result is going to be useless - the keys are clearly important here, with the values being (presumably) anonymous 1/0 flags.
14
foreach($arr as $key => $value)
{
   if(preg_match('/^foo-/', $key))
   {
        // You can access $value or create a new array based off these values
   }
}

3 Comments

A regex is not really necessary in this case. The substr method is slightly more efficient
@jfoucher: That's true, however, personally, it's easier to read.
It may be more flexible, but comes at the cost of needing to escape special preg characters if you don't want to do a regular expression match. So use with caution. I would suggest you use REs only if you need REs.
8

Modification to erisco's Functional approach,

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

this worked for me.

3 Comments

Any difference in performance or usefulness compared to array_filter_key version provided by @erisco?
Nope. There should not any difference in performance I guess. @MaciekSemik
This is a core PHP function so it should be preferred.
3

In addition to @Suresh Velusamy's answer above (which needs at least PHP 5.6.0) you can use the following if you are on a prior version of 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
)
*/

1 Comment

Please note (or at least for me) that this only returns the array key's that match. The answer below by @suresh-velusamy extracts the actual array with the original $key => $value pair. It is stated in the output of this answer, but was not yet mentioned explicitly
2

From PHP5.6, the array keys can be the sole subject of the filtration by using the ARRAY_FILTER_USE_KEY constant/flag.

From PHP7.4, arrow functions make custom functions more concise and allow values to be passed into the custom function's scope without use().

From PHP8, str_starts_with() can take the place of strpos(...) === 0

Code: (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
    )
);

Output:

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

Comments

1

You might pass a key-value single dimensional array and a specific prefix string 'foo-' to the function just made: filter_array_key_with_prefix

<?php

function filter_array_key_with_prefix($arr, $prefix) {
  return array_filter($arr, function($k) use ($prefix) {
    return strpos($k, $prefix) === 0;
  }, ARRAY_FILTER_USE_KEY);
}

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

$filtered = filter_array_key_with_prefix($arr, 'foo-');

var_dump($filtered);

Output:

array(3) {
  ["foo-bcd"]=>
  int(1)
  ["foo-def"]=>
  int(1)
  ["foo-xyz"]=>
  int(0)
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.