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?
$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";
}
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
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;
}
}
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))
);
This can be handled using a closure. The following answer is inspired by PHP The Right Way:
//This will create an anonymous function that will filter the items in the array by the value supplied
function cb_equal_to($val)
{
return function($item) use ($val) {
return $item == $val;
};
}
$input = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
// Use array_filter on a input with a selected filter function
$filtered_array = array_filter($input, cb_equal_to(2));
Contents of $filtered_array would now be
array ( ["a"] => 2 ["c"] => 2 ["f"] => 2 )
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.
From PHP7.4, arrow function syntax is available. This affords more concise code and the ability to access global variables without use.
Code: (Demo)
$haystack = [
"a" => 2,
"b" => 4,
"c" => 2,
"d" => 5,
"e" => 6,
"f" => 2
];
$needle = 2;
var_export(
array_filter(
$haystack,
fn($v) => $v === $needle
)
);
I might do something like:
$newarray = array();
foreach ($jsonarray as $testelement){
if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);
foreach ($aray as $key => $value) {
if (2 != $value) {
unset($array($key));
}
}
echo 'Items in array:' . count($array);
You can do something like:
$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
$arrayFiltered = array_filter($array, function ($element) {
return $element == 2;
});
or:
$arrayFiltered = array_filter($array, fn($element) => $element == 2);
Related
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?
$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";
}
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
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;
}
}
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))
);
This can be handled using a closure. The following answer is inspired by PHP The Right Way:
//This will create an anonymous function that will filter the items in the array by the value supplied
function cb_equal_to($val)
{
return function($item) use ($val) {
return $item == $val;
};
}
$input = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
// Use array_filter on a input with a selected filter function
$filtered_array = array_filter($input, cb_equal_to(2));
Contents of $filtered_array would now be
array ( ["a"] => 2 ["c"] => 2 ["f"] => 2 )
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.
From PHP7.4, arrow function syntax is available. This affords more concise code and the ability to access global variables without use.
Code: (Demo)
$haystack = [
"a" => 2,
"b" => 4,
"c" => 2,
"d" => 5,
"e" => 6,
"f" => 2
];
$needle = 2;
var_export(
array_filter(
$haystack,
fn($v) => $v === $needle
)
);
I might do something like:
$newarray = array();
foreach ($jsonarray as $testelement){
if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);
foreach ($aray as $key => $value) {
if (2 != $value) {
unset($array($key));
}
}
echo 'Items in array:' . count($array);
You can do something like:
$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
$arrayFiltered = array_filter($array, function ($element) {
return $element == 2;
});
or:
$arrayFiltered = array_filter($array, fn($element) => $element == 2);
I have an associative array from which I need a new array to be created. I am targeting the peak values for the new array. For a value to be selected to the new array, it needs to be higher than both the previous and the next value in the array.
I have searched the net and found a function that could handle the situation for indexed arrays - but not for associative arrays. Here is what I would like:
$array = array('a' => 0, 'b' => 2, 'c' => 1, 'd' => 2, 'e' => 3);
$result = array('b' => 2, 'e' => 3);
The function usable for indexed arrays look like this:
$a = array(0, 2, 1, 2, 3);
$b = array_filter($a, function($v, $k) use($a) {
return $k > 0 && $v > $a[$k-1] && $k + 1 < count($a) && $v > $a[$k+1];
}, ARRAY_FILTER_USE_BOTH );
This function doesn't include the last value either.
You should change the condition if you really want to get border items. But an approach could be to use the array of keys to get prev and next items
$array = array('a' => 0, 'b' => 2, 'c' => 1, 'd' => 2, 'e' => 3);
$keys = array_keys($array);
$b = array_filter($array, function($v, $k) use($array, $keys) {
$k = array_search($k, $keys);
return $k > 0 && $v > $array[$keys[$k-1]] && $k + 1 < count($keys) && $v > $array[$keys[$k+1]];
}, ARRAY_FILTER_USE_BOTH );
print_r($b);
This can be done with zero iterated function calls.
Before looping declare a lookup array by assigning indices to the input array's keys -- array_keys().
Then in the loop use conditional fallback values and null coalescing when an attempt to access a non-existent element occurs.
($i ? $array[$keys[$i - 1]] : $array[$key] - 1) means: if $i is not zero, then access the value from the input array by its key which is one position before the current key. Otherwise, $i equals zero which means there is no earlier value so fallback to the current value minus one to guarantee it will be less in the comparison.
($array[$keys[$i + 1] ?? -1] ?? $array[$key] - 1) means: try to access the next key in the lookup array, if it does not exist, use negative one which is guaranteed not to exist. By effect, when $i is that last index in the loop, there will be no next key, so fallback to the current value minus one again.
This should always outperform any script that makes iterated function calls.
Code: (Demo)
$array = ['a' => 0, 'b' => 2, 'c' => 1, 'd' => 2, 'e' => 3];
$keys = array_keys($array);
foreach ($keys as $i => $key) {
if ($array[$key] > ($i ? $array[$keys[$i - 1]] : $array[$key] - 1)
&& $array[$key] > ($array[$keys[$i + 1] ?? -1] ?? $array[$key] - 1)
) {
$result[$key] = $array[$key];
}
}
var_export($result);
Output:
array (
'b' => 2,
'e' => 3,
)
Alternatively, if you want to mutate the input array, you can call unset() in the loop and simply invert the conditional logic.
I worked #splash58. Thank you. I have none the less tried something myself which also worked - but I don't know which solution is most effective.
$result = array();
$value1 = NULL;
foreach (array_reverse($array) as $key => $value) {
if ($value > $value1) {
$result[$key] = $value;
}
$value1 = $value;
}
and is '$value1 = NULL' this necessary?
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?
$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";
}
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
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;
}
}
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))
);
This can be handled using a closure. The following answer is inspired by PHP The Right Way:
//This will create an anonymous function that will filter the items in the array by the value supplied
function cb_equal_to($val)
{
return function($item) use ($val) {
return $item == $val;
};
}
$input = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
// Use array_filter on a input with a selected filter function
$filtered_array = array_filter($input, cb_equal_to(2));
Contents of $filtered_array would now be
array ( ["a"] => 2 ["c"] => 2 ["f"] => 2 )
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.
From PHP7.4, arrow function syntax is available. This affords more concise code and the ability to access global variables without use.
Code: (Demo)
$haystack = [
"a" => 2,
"b" => 4,
"c" => 2,
"d" => 5,
"e" => 6,
"f" => 2
];
$needle = 2;
var_export(
array_filter(
$haystack,
fn($v) => $v === $needle
)
);
I might do something like:
$newarray = array();
foreach ($jsonarray as $testelement){
if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);
foreach ($aray as $key => $value) {
if (2 != $value) {
unset($array($key));
}
}
echo 'Items in array:' . count($array);
You can do something like:
$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
$arrayFiltered = array_filter($array, function ($element) {
return $element == 2;
});
or:
$arrayFiltered = array_filter($array, fn($element) => $element == 2);
I would like to validate that an array has and only has "a", "b", and "c" as associate keys, and that the values are either integers or either NULL or 0 (what ever is easier).
For instance, array('a'=>123,'b'=>'abc', 'd'=>321) should be converted to array('a'=>123,'b'=>0, 'c'=>0).
I can do something like the following, but it is a little difficult to read, and will become big if I don't just have 3 elements but 300.
$newArr=array(
'a' => (isset($arr['a'])) ? (int)$arr['a'] : 0,
'b' => (isset($arr['b'])) ? (int)$arr['b'] : 0,
'c' => (isset($arr['c'])) ? (int)$arr['c'] : 0
);
Another option is something like the following:
$newArr = array();
foreach (array('a','b','c') as $key)
{
$newArr[$key] = (isset($arr[$key])) ? (int)$arr[$key] : 0;
}
I guess this works good enough, however, am curious whether there is some slick array converting function that I don't know about that would be better.
It is possible to re-write your function using a combination of:
array_intersect_key to remove extra keys
array_merge to add missing keys
array_map to change every thing to NULL or integer
However, this only makes it complicated. The slickest way IMO is this:
$test = array("a" => 123, "b" => "x", "d" => 123);
$testcopy = array();
foreach (array("a", "b", "c") as $key) {
$testcopy[$key] = array_key_exists($key, $test)
? filter_var($test[$key], FILTER_VALIDATE_INT, array("options" => array("default" => NULL)))
: NULL;
}
var_dump($testcopy);
Output:
array(3) {
["a"]=> int(123)
["b"]=> NULL
["c"]=> NULL
}
Here's a possible solution...
// create array of required keys with default values
$defaultKeys = array('a','b','c');
$defaultVals = array_fill(0, count($defaultKeys), 0);
$defaults = array_combine($defaultKeys, $defaultVals);
$args = array('a'=>123,'b'=>'abc', 'd'=>321);
// merge arguments with defaults, overwriting default values with arg values and preserving keys
$args = array_merge($defaults, $args);
// remove key/value pairs present in args that don't exist in defaults
$args = array_intersect_key($args, $defaults);
// filter values, replacing anything that isn't an integer of 0 or greater value with a 0
$args = array_map( function($v) { return (is_integer($v) && $v >= 0) ? $v : 0; }, $args );
array map is nice http://php.net/manual/en/function.array-map.php
$arr = array('a'=>123,'b'=>'abc', 'd'=>321);
function intize($n){return (int)$n;}
$arr = array_map("intize",$arr);
print_r($arr);
or for the keys, array_walk
$arr = array('a'=>123,'b'=>'abc', 'd'=>321);
function intize(&$n,$key){
if($key =='a'||$key=='b'||$key=='c')
$n= (int)$n;
else
unset($n);
}
array_walk($arr,"intize");
print_r($arr);
Establish a default/lookup array, then as you iterate it you can compares its keys against the user input and check if qualifying elements have qualifying values.
The two below techniques are "slick", in my opinion, and will make your code easy to maintain because you will only ever need to maintain the default array.
Codes: (Demo)
$array = ["a" => 123, "b" => "x", "d" => 123];
$default = ["a" => null, "b" => null, "c" => null];
Functional style:
var_export(
array_replace(
$default,
array_filter(
array_intersect_key($array, $default),
'is_int'
)
)
);
Language construct iteration (modify the default array):
foreach ($default as $k => &$v) {
if (isset($array[$k]) && is_int($array[$k])) {
$default[$k] = $array[$k];
}
}
var_export($default);
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?
$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";
}
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
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;
}
}
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))
);
This can be handled using a closure. The following answer is inspired by PHP The Right Way:
//This will create an anonymous function that will filter the items in the array by the value supplied
function cb_equal_to($val)
{
return function($item) use ($val) {
return $item == $val;
};
}
$input = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
// Use array_filter on a input with a selected filter function
$filtered_array = array_filter($input, cb_equal_to(2));
Contents of $filtered_array would now be
array ( ["a"] => 2 ["c"] => 2 ["f"] => 2 )
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.
From PHP7.4, arrow function syntax is available. This affords more concise code and the ability to access global variables without use.
Code: (Demo)
$haystack = [
"a" => 2,
"b" => 4,
"c" => 2,
"d" => 5,
"e" => 6,
"f" => 2
];
$needle = 2;
var_export(
array_filter(
$haystack,
fn($v) => $v === $needle
)
);
I might do something like:
$newarray = array();
foreach ($jsonarray as $testelement){
if ($testelement == 2){$newarray[]=$testelement}
}
$result = count($newarray);
foreach ($aray as $key => $value) {
if (2 != $value) {
unset($array($key));
}
}
echo 'Items in array:' . count($array);
You can do something like:
$array = array("a" => 2, "b" => 4, "c" => 2, "d" => 5, "e" => 6, "f" => 2);
$arrayFiltered = array_filter($array, function ($element) {
return $element == 2;
});
or:
$arrayFiltered = array_filter($array, fn($element) => $element == 2);