By menardmam


2009-10-01 12:09:34 8 Comments

I have an array like this:

array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2)

Now I want to filter that array by some condition and only keep the elements where the value is equal to 2 and delete all elements where the value is NOT 2.

So my expected result array would be:

array("a" => 2, "c" => 2, "f" => 2)

Note: I want to keep the keys from the original array.

How can I do that with PHP? Any built-in functions?

7 comments

@mickmackusa 2018-07-03 02:49:45

I think the snappiest, readable built-in function is: array_intersect()

Code: (Demo)

$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
var_export(array_intersect($array, [2]));

Output:

array (
  'a' => 2,
  'c' => 2,
  'f' => 2,
)

Just make sure you declare the 2nd parameter as an array because that is the value type expected.

Now there is nothing wrong with writing out a foreach loop, or using array_filter(), they just have a more verbose syntax.

array_intersect() is also very easy to extend (include additional "qualifying" values) by adding more values to the 2nd parameter array.

@Gumbo 2009-10-01 12:13:50

You somehow have to loop through your array and filter each element by your condition. This can be done with various methods.

Loops while / for / foreach method

Loop through your array with any loop you want, may it be while, for or foreach. Then simply check for your condition and either unset() the elements if they don't meet your condition or write the elements, which meet the condition, into a new array.

Looping

//while loop
while(list($key, $value) = each($array)){
    //condition
}

//for loop
$keys = array_keys($array);
for($counter = 0, $length = count($array); $counter < $length; $counter++){
    $key = $keys[$counter];
    $value = $array[$key];
    //condition 
}

//foreach loop
foreach($array as $key => $value){
    //condition
}

Condition

Just place your condition into the loop where the comment //condition is. The condition can just check for whatever you want and then you can either unset() the elements which don't meet your condition, and reindex the array with array_values() if you want, or write the elements in a new array which meet the condition.

//Pseudo code
//Use one of the two ways
if(condition){  //1. Condition fulfilled
    $newArray[ ] = $value;
            //↑ Put '$key' there, if you want to keep the original keys
            //Result array is: $newArray

} else {        //2. Condition NOT fulfilled
    unset($array[$key]);
    //Use array_values() after the loop if you want to reindex the array
    //Result array is: $array
}

array_filter() method

Another method is to use the array_filter() built-in function. It generally works pretty much the same as the method with a simple loop.

You just need to return TRUE if you want to keep the element in the array and FALSE if you want to drop the element out of the result array.

//Anonymous function
$newArray = array_filter($array, function($value, $key){
    //condition
}, ARRAY_FILTER_USE_BOTH);

//Function name passed as string
function filter($value, $key){
    //condition
}
$newArray = array_filter($array, "filter", ARRAY_FILTER_USE_BOTH);

//'create_function()', NOT recommended
$newArray = array_filter($array, create_function('$value, $key', '/* condition */'), ARRAY_FILTER_USE_BOTH);

preg_grep() method

preg_grep() is similar to array_filter() just that it only uses regular expression to filter the array. So you might not be able to do everything with it, since you can only use a regular expression as filter and you can only filter by values or with some more code by keys.

Also note that you can pass the flag PREG_GREP_INVERT as third parameter to invert the results.

//Filter by values
$newArray = preg_grep("/regex/", $array);

Common conditions

There are many common conditions used to filter an array of which all can be applied to the value and or key of the array. I will just list a few of them here:

//Odd values
return $value & 1;

//Even values
return !($value & 1);

//NOT null values
return !is_null($value);

//NOT 0 values
return $value !== 0;

//Contain certain value values
return strpos($value, $needle) !== FALSE;  //Use 'use($needle)' to get the var into scope

//Contain certain substring at position values
return substr($value, $position, $length) === $subString;

//NOT 'empty'(link) values
array_filter($array);  //Leave out the callback parameter

@Simon 2009-10-01 12:16:33

It doesn't pass $arr by reference, and instead returns a new array which you're not capturing.

@Gumbo 2009-10-01 13:23:34

@Simon: The manual is not just for book worms. All developers should be able and smart enough to read it. But maybe most expect a copy & paste example where they don’t have to think.

@Tom Haigh 2009-10-01 13:19:10

This should work, but I'm not sure how efficient it is as you probably end up copying a lot of data.

$newArray = array_intersect_key(
                  $fullarray, 
                  array_flip(array_keys($fullarray, 2))
            );

@soulmerge 2009-10-01 12:14:00

You can iterate on the copies of the keys to be able to use unset() in the loop:

foreach (array_keys($array) as $key) {
    if ($array[$key] != 2)  {
        unset($array[$key]);
    }
}

The advantage of this method is memory efficiency if your array contains big values - they are not duplicated.

EDIT I just noticed, that you actually only need the keys that have a value of 2 (you already know the value):

$keys = array();
foreach ($array as $key => $value) {
    if ($value == 2)  {
        $keys[] = $key;
    }
}

@Goran Jurić 2009-10-01 12:15:47

  foreach ($aray as $key => $value) {
    if (2 != $value) {
      unset($array($key));
    }
  }

  echo 'Items in array:' . count($array);

@Alex Mcp 2009-10-01 12:14:56

I might do something like:

$newarray = array();
foreach ($jsonarray as $testelement){
    if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);

@Simon 2009-10-01 12:13:41

$fullarray = array('a'=>2,'b'=>4,'c'=>2,'d'=>5,'e'=>6,'f'=>2);


function filterArray($value){
    return ($value == 2);
}

$filteredArray = array_filter($fullArray, 'filterArray');

foreach($filteredArray as $k => $v){
    echo "$k = $v";
}

@menardmam 2009-10-01 15:28:42

that ask to make a different function for each request... is it possible to ass an extra var ? (2 as variable)

@Benjamin 2019-01-17 17:08:56

It would be nice to update this answer to use a closure, to teach best practices in 2019!

Related Questions

Sponsored Content

33 Answered Questions

[SOLVED] For-each over an array in JavaScript?

25 Answered Questions

[SOLVED] PHP array delete by value (not key)

  • 2011-08-29 00:44:04
  • Adam Strudwick
  • 756524 View
  • 814 Score
  • 25 Answer
  • Tags:   php arrays

47 Answered Questions

86 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 6041520 View
  • 7522 Score
  • 86 Answer
  • Tags:   javascript arrays

52 Answered Questions

[SOLVED] How to check if PHP array is associative or sequential?

  • 2008-10-06 07:01:13
  • Wilco
  • 236990 View
  • 740 Score
  • 52 Answer
  • Tags:   php arrays

7 Answered Questions

[SOLVED] How does PHP 'foreach' actually work?

18 Answered Questions

[SOLVED] Reference — What does this symbol mean in PHP?

34 Answered Questions

[SOLVED] Create ArrayList from array

30 Answered Questions

[SOLVED] How to append something to an array?

12 Answered Questions

[SOLVED] How can I add new array elements at the beginning of an array in Javascript?

  • 2011-11-10 00:35:22
  • Moon
  • 733017 View
  • 1456 Score
  • 12 Answer
  • Tags:   javascript arrays

Sponsored Content