Some elements in my array are empty strings based on what the user has submitted. I need to remove those elements. I have this:
foreach($linksArray as $link)
{
if($link == '')
{
unset($link);
}
}
print_r($linksArray);
But it doesn't work. $linksArray still has empty elements. I have also tried doing it with the empty() function, but the outcome is the same.
As you're dealing with an array of strings, you can simply use array_filter(), which conveniently handles all this for you:
print_r(array_filter($linksArray));
Keep in mind that if no callback is supplied, all entries of array equal to FALSE (see converting to boolean) will be removed. So if you need to preserve elements that are i.e. exact string '0', you will need a custom callback:
// PHP 7.4 and later
print_r(array_filter($linksArray, fn($value) => !is_null($value) && $value !== ''));
// PHP 5.3 and later
print_r(array_filter($linksArray, function($value) { return !is_null($value) && $value !== ''; }));
// PHP < 5.3
print_r(array_filter($linksArray, create_function('$value', 'return $value !== "";')));
Note: If you need to reindex the array after removing the empty elements, use: $linksArray = array_values(array_filter($linksArray));
You can use array_filter to remove empty elements:
$emptyRemoved = array_filter($linksArray);
If you have (int) 0 in your array, you may use the following:
$emptyRemoved = remove_empty($linksArray);
function remove_empty($array) {
return array_filter($array, '_remove_empty_internal');
}
function _remove_empty_internal($value) {
return !empty($value) || $value === 0;
}
EDIT: Maybe your elements are not empty per se but contain one or more spaces... You can use the following before using array_filter
$trimmedArray = array_map('trim', $linksArray);
The most popular answer on this topic is absolutely INCORRECT.
Consider the following PHP script:
<?php
$arr = array('1', '', '2', '3', '0');
// Incorrect:
print_r(array_filter($arr));
// Correct:
print_r(array_filter($arr, 'strlen'));
Why is this? Because a string containing a single '0' character also evaluates to boolean false, so even though it's not an empty string, it will still get filtered. That would be a bug.
Passing the built-in strlen function as the filtering function will work, because it returns a non-zero integer for a non-empty string, and a zero integer for an empty string. Non-zero integers always evaluate to true when converted to boolean, while zero integers always evaluate to false when converted to boolean.
So, the absolute, definitive, correct answer is:
$arr = array_filter($arr, 'strlen');
$linksArray = array_filter($linksArray);
"If no callback is supplied, all entries of input equal to FALSE will be removed." -- http://php.net/manual/en/function.array-filter.php
$myarray = array_filter($myarray, 'strlen'); //removes null values but leaves "0"
$myarray = array_filter($myarray); //removes all null values
You can just do
array_filter($array)
array_filter: "If no callback is supplied, all entries of input equal to FALSE will be removed." This means that elements with values NULL, 0, '0', '', FALSE, array() will be removed too.
The other option is doing
array_diff($array, array(''))
which will remove elements with values NULL, '' and FALSE.
Hope this helps :)
UPDATE
Here is an example.
$a = array(0, '0', NULL, FALSE, '', array());
var_dump(array_filter($a));
// array()
var_dump(array_diff($a, array(0))) // 0 / '0'
// array(NULL, FALSE, '', array());
var_dump(array_diff($a, array(NULL))) // NULL / FALSE / ''
// array(0, '0', array())
To sum up:
0 or '0' will remove 0 and '0'
NULL, FALSE or '' will remove NULL, FALSE and ''
foreach($linksArray as $key => $link)
{
if($link === '')
{
unset($linksArray[$key]);
}
}
print_r($linksArray);
In short:
This is my suggested code:
$myarray = array_values(array_filter(array_map('trim', $myarray), 'strlen'));
Explanation:
I thinks use array_filter is good, but not enough, because values be like space and \n,... keep in the array and this is usually bad.
So I suggest you use mixture array_filter and array_map.
array_map is for trimming, array_filter is for remove empty values, strlen is for keep 0 value, and array_values is for re indexing if you needed.
Samples:
$myarray = array("\r", "\n", "\r\n", "", " ", "0", "a");
// "\r", "\n", "\r\n", " ", "a"
$new1 = array_filter($myarray);
// "a"
$new2 = array_filter(array_map('trim', $myarray));
// "0", "a"
$new3 = array_filter(array_map('trim', $myarray), 'strlen');
// "0", "a" (reindex)
$new4 = array_values(array_filter(array_map('trim', $myarray), 'strlen'));
var_dump($new1, $new2, $new3, $new4);
Results:
array(5) {
[0]=>
" string(1) "
[1]=>
string(1) "
"
[2]=>
string(2) "
"
[4]=>
string(1) " "
[6]=>
string(1) "a"
}
array(1) {
[6]=>
string(1) "a"
}
array(2) {
[5]=>
string(1) "0"
[6]=>
string(1) "a"
}
array(2) {
[0]=>
string(1) "0"
[1]=>
string(1) "a"
}
Online Test:
http://sandbox.onlinephpfunctions.com/code/e02f5d8795938be9f0fa6f4c17245a9bf8777404
Another one liner to remove empty ("" empty string) elements from your array.
$array = array_filter($array, function($a) {return $a !== "";});
Note: This code deliberately keeps null, 0 and false elements.
Or maybe you want to trim your array elements first:
$array = array_filter($array, function($a) {
return trim($a) !== "";
});
Note: This code also removes null and false elements.
If you are working with a numerical array and need to re-index the array after removing empty elements, use the array_values function:
array_values(array_filter($array));
Also see: PHP reindex array?
The most voted answer is wrong or at least not completely true as the OP is talking about blank strings only. Here's a thorough explanation:
What does empty mean?
First of all, we must agree on what empty means. Do you mean to filter out:
the empty strings only ("")?
the strictly false values? ($element === false)
the falsey values? (i.e. 0, 0.0, "", "0", NULL, array()...)
the equivalent of PHP's empty() function?
How do you filter out the values
To filter out empty strings only:
$filtered = array_diff($originalArray, array(""));
To only filter out strictly false values, you must use a callback function:
$filtered = array_diff($originalArray, 'myCallback');
function myCallback($var) {
return $var === false;
}
The callback is also useful for any combination in which you want to filter out the "falsey" values, except some. (For example, filter every null and false, etc, leaving only 0):
$filtered = array_filter($originalArray, 'myCallback');
function myCallback($var) {
return ($var === 0 || $var === '0');
}
Third and fourth case are (for our purposes at last) equivalent, and for that all you have to use is the default:
$filtered = array_filter($originalArray);
$a = array(1, '', '', '', 2, '', 3, 4);
$b = array_values(array_filter($a));
print_r($b)
For multidimensional array
$data = array_map('array_filter', $data);
$data = array_filter($data);
I had to do this in order to keep an array value of (string) 0
$url = array_filter($data, function ($value) {
return (!empty($value) || $value === 0 || $value==='0');
});
$out_array = array_filter($input_array, function($item)
{
return !empty($item['key_of_array_to_check_whether_it_is_empty']);
}
);
function trim_array($Array)
{
foreach ($Array as $value) {
if(trim($value) === '') {
$index = array_search($value, $Array);
unset($Array[$index]);
}
}
return $Array;
}
Just want to contribute an alternative to loops...also addressing gaps in keys...
In my case, I wanted to keep sequential array keys when the operation was complete (not just odd numbers, which is what I was staring at. Setting up code to look just for odd keys seemed fragile to me and not future-friendly.)
I was looking for something more like this: http://gotofritz.net/blog/howto/removing-empty-array-elements-php/
The combination of array_filter and array_slice does the trick.
$example = array_filter($example);
$example = array_slice($example,0);
No idea about efficiencies or benchmarks but it works.
I use the following script to remove empty elements from an array
for ($i=0; $i<$count($Array); $i++)
{
if (empty($Array[$i])) unset($Array[$i]);
}
$my = ("0"=>" ","1"=>"5","2"=>"6","3"=>" ");
foreach ($my as $key => $value) {
if (is_null($value)) unset($my[$key]);
}
foreach ($my as $key => $value) {
echo $key . ':' . $value . '<br>';
}
output
1:5
2:6
foreach($arr as $key => $val){
if (empty($val)) unset($arr[$key];
}
Just one line :
Update (thanks to #suther):
$array_without_empty_values = array_filter($array);
use array_filter function to remove empty values:
$linksArray = array_filter($linksArray);
print_r($linksArray);
Remove empty array elements
function removeEmptyElements(&$element)
{
if (is_array($element)) {
if ($key = key($element)) {
$element[$key] = array_filter($element);
}
if (count($element) != count($element, COUNT_RECURSIVE)) {
$element = array_filter(current($element), __FUNCTION__);
}
return $element;
} else {
return empty($element) ? false : $element;
}
}
$data = array(
'horarios' => array(),
'grupos' => array(
'1A' => array(
'Juan' => array(
'calificaciones' => array(
'Matematicas' => 8,
'Español' => 5,
'Ingles' => 9,
),
'asistencias' => array(
'enero' => 20,
'febrero' => 10,
'marzo' => '',
)
),
'Damian' => array(
'calificaciones' => array(
'Matematicas' => 10,
'Español' => '',
'Ingles' => 9,
),
'asistencias' => array(
'enero' => 20,
'febrero' => '',
'marzo' => 5,
)
),
),
'1B' => array(
'Mariana' => array(
'calificaciones' => array(
'Matematicas' => null,
'Español' => 7,
'Ingles' => 9,
),
'asistencias' => array(
'enero' => null,
'febrero' => 5,
'marzo' => 5,
)
),
),
)
);
$data = array_filter($data, 'removeEmptyElements');
var_dump($data);
¡it works!
As per your method, you can just catch those elements in an another array and use that one like follows,
foreach($linksArray as $link){
if(!empty($link)){
$new_arr[] = $link
}
}
print_r($new_arr);
I think array_walk is much more suitable here
$linksArray = array('name', ' ', ' 342', '0', 0.0, null, '', false);
array_walk($linksArray, function(&$v, $k) use (&$linksArray){
$v = trim($v);
if ($v == '')
unset($linksArray[$k]);
});
print_r($linksArray);
Output:
Array
(
[0] => name
[2] => 342
[3] => 0
[4] => 0
)
We made sure that empty values are removed even if the user adds more than one space
We also trimmed empty spaces from the valid values
Finally, only (null), (Boolean False) and ('') will be considered empty strings
As for False it's ok to remove it, because AFAIK the user can't submit boolean values.
With these types of things, it's much better to be explicit about what you want and do not want.
It will help the next guy to not get caught by surprise at the behaviour of array_filter() without a callback. For example, I ended up on this question because I forgot if array_filter() removes NULL or not. I wasted time when I could have just used the solution below and had my answer.
Also, the logic is language angnostic in the sense that the code can be copied into another language without having to under stand the behaviour of a php function like array_filter when no callback is passed.
In my solution, it is clear at glance as to what is happening. Remove a conditional to keep something or add a new condition to filter additional values.
Disregard the actual use of array_filter() since I am just passing it a custom callback - you could go ahead and extract that out to its own function if you wanted. I am just using it as sugar for a foreach loop.
<?php
$xs = [0, 1, 2, 3, "0", "", false, null];
$xs = array_filter($xs, function($x) {
if ($x === null) { return false; }
if ($x === false) { return false; }
if ($x === "") { return false; }
if ($x === "0") { return false; }
return true;
});
$xs = array_values($xs); // reindex array
echo "<pre>";
var_export($xs);
Another benefit of this approach is that you can break apart the filtering predicates into an abstract function that filters a single value per array and build up to a composable solution.
See this example and the inline comments for the output.
<?php
/**
* #param string $valueToFilter
*
* #return \Closure A function that expects a 1d array and returns an array
* filtered of values matching $valueToFilter.
*/
function filterValue($valueToFilter)
{
return function($xs) use ($valueToFilter) {
return array_filter($xs, function($x) use ($valueToFilter) {
return $x !== $valueToFilter;
});
};
}
// partially applied functions that each expect a 1d array of values
$filterNull = filterValue(null);
$filterFalse = filterValue(false);
$filterZeroString = filterValue("0");
$filterEmptyString = filterValue("");
$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterNull($xs); //=> [0, 1, 2, 3, false, "0", ""]
$xs = $filterFalse($xs); //=> [0, 1, 2, 3, "0", ""]
$xs = $filterZeroString($xs); //=> [0, 1, 2, 3, ""]
$xs = $filterEmptyString($xs); //=> [0, 1, 2, 3]
echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
Now you can dynamically create a function called filterer() using pipe() that will apply these partially applied functions for you.
<?php
/**
* Supply between 1..n functions each with an arity of 1 (that is, accepts
* one and only one argument). Versions prior to php 5.6 do not have the
* variadic operator `...` and as such require the use of `func_get_args()` to
* obtain the comma-delimited list of expressions provided via the argument
* list on function call.
*
* Example - Call the function `pipe()` like:
*
* pipe ($addOne, $multiplyByTwo);
*
* #return closure
*/
function pipe()
{
$functions = func_get_args(); // an array of callable functions [$addOne, $multiplyByTwo]
return function ($initialAccumulator) use ($functions) { // return a function with an arity of 1
return array_reduce( // chain the supplied `$arg` value through each function in the list of functions
$functions, // an array of functions to reduce over the supplied `$arg` value
function ($accumulator, $currFn) { // the reducer (a reducing function)
return $currFn($accumulator);
},
$initialAccumulator
);
};
}
/**
* #param string $valueToFilter
*
* #return \Closure A function that expects a 1d array and returns an array
* filtered of values matching $valueToFilter.
*/
function filterValue($valueToFilter)
{
return function($xs) use ($valueToFilter) {
return array_filter($xs, function($x) use ($valueToFilter) {
return $x !== $valueToFilter;
});
};
}
$filterer = pipe(
filterValue(null),
filterValue(false),
filterValue("0"),
filterValue("")
);
$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterer($xs);
echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
try this **
**Example
$or = array(
'PersonalInformation.first_name' => $this->request->data['User']['first_name'],
'PersonalInformation.last_name' => $this->request->data['User']['last_name'],
'PersonalInformation.primary_phone' => $this->request->data['User']['primary_phone'],
'PersonalInformation.dob' => $this->request->data['User']['dob'],
'User.email' => $this->request->data['User']['email'],
);
$or = array_filter($or);
$condition = array(
'User.role' => array('U', 'P'),
'User.user_status' => array('active', 'lead', 'inactive'),
'OR' => $or
);
Related
Some elements in my array are empty strings based on what the user has submitted. I need to remove those elements. I have this:
foreach($linksArray as $link)
{
if($link == '')
{
unset($link);
}
}
print_r($linksArray);
But it doesn't work. $linksArray still has empty elements. I have also tried doing it with the empty() function, but the outcome is the same.
As you're dealing with an array of strings, you can simply use array_filter(), which conveniently handles all this for you:
print_r(array_filter($linksArray));
Keep in mind that if no callback is supplied, all entries of array equal to FALSE (see converting to boolean) will be removed. So if you need to preserve elements that are i.e. exact string '0', you will need a custom callback:
// PHP 7.4 and later
print_r(array_filter($linksArray, fn($value) => !is_null($value) && $value !== ''));
// PHP 5.3 and later
print_r(array_filter($linksArray, function($value) { return !is_null($value) && $value !== ''; }));
// PHP < 5.3
print_r(array_filter($linksArray, create_function('$value', 'return $value !== "";')));
Note: If you need to reindex the array after removing the empty elements, use: $linksArray = array_values(array_filter($linksArray));
You can use array_filter to remove empty elements:
$emptyRemoved = array_filter($linksArray);
If you have (int) 0 in your array, you may use the following:
$emptyRemoved = remove_empty($linksArray);
function remove_empty($array) {
return array_filter($array, '_remove_empty_internal');
}
function _remove_empty_internal($value) {
return !empty($value) || $value === 0;
}
EDIT: Maybe your elements are not empty per se but contain one or more spaces... You can use the following before using array_filter
$trimmedArray = array_map('trim', $linksArray);
The most popular answer on this topic is absolutely INCORRECT.
Consider the following PHP script:
<?php
$arr = array('1', '', '2', '3', '0');
// Incorrect:
print_r(array_filter($arr));
// Correct:
print_r(array_filter($arr, 'strlen'));
Why is this? Because a string containing a single '0' character also evaluates to boolean false, so even though it's not an empty string, it will still get filtered. That would be a bug.
Passing the built-in strlen function as the filtering function will work, because it returns a non-zero integer for a non-empty string, and a zero integer for an empty string. Non-zero integers always evaluate to true when converted to boolean, while zero integers always evaluate to false when converted to boolean.
So, the absolute, definitive, correct answer is:
$arr = array_filter($arr, 'strlen');
$linksArray = array_filter($linksArray);
"If no callback is supplied, all entries of input equal to FALSE will be removed." -- http://php.net/manual/en/function.array-filter.php
$myarray = array_filter($myarray, 'strlen'); //removes null values but leaves "0"
$myarray = array_filter($myarray); //removes all null values
You can just do
array_filter($array)
array_filter: "If no callback is supplied, all entries of input equal to FALSE will be removed." This means that elements with values NULL, 0, '0', '', FALSE, array() will be removed too.
The other option is doing
array_diff($array, array(''))
which will remove elements with values NULL, '' and FALSE.
Hope this helps :)
UPDATE
Here is an example.
$a = array(0, '0', NULL, FALSE, '', array());
var_dump(array_filter($a));
// array()
var_dump(array_diff($a, array(0))) // 0 / '0'
// array(NULL, FALSE, '', array());
var_dump(array_diff($a, array(NULL))) // NULL / FALSE / ''
// array(0, '0', array())
To sum up:
0 or '0' will remove 0 and '0'
NULL, FALSE or '' will remove NULL, FALSE and ''
foreach($linksArray as $key => $link)
{
if($link === '')
{
unset($linksArray[$key]);
}
}
print_r($linksArray);
In short:
This is my suggested code:
$myarray = array_values(array_filter(array_map('trim', $myarray), 'strlen'));
Explanation:
I thinks use array_filter is good, but not enough, because values be like space and \n,... keep in the array and this is usually bad.
So I suggest you use mixture array_filter and array_map.
array_map is for trimming, array_filter is for remove empty values, strlen is for keep 0 value, and array_values is for re indexing if you needed.
Samples:
$myarray = array("\r", "\n", "\r\n", "", " ", "0", "a");
// "\r", "\n", "\r\n", " ", "a"
$new1 = array_filter($myarray);
// "a"
$new2 = array_filter(array_map('trim', $myarray));
// "0", "a"
$new3 = array_filter(array_map('trim', $myarray), 'strlen');
// "0", "a" (reindex)
$new4 = array_values(array_filter(array_map('trim', $myarray), 'strlen'));
var_dump($new1, $new2, $new3, $new4);
Results:
array(5) {
[0]=>
" string(1) "
[1]=>
string(1) "
"
[2]=>
string(2) "
"
[4]=>
string(1) " "
[6]=>
string(1) "a"
}
array(1) {
[6]=>
string(1) "a"
}
array(2) {
[5]=>
string(1) "0"
[6]=>
string(1) "a"
}
array(2) {
[0]=>
string(1) "0"
[1]=>
string(1) "a"
}
Online Test:
http://sandbox.onlinephpfunctions.com/code/e02f5d8795938be9f0fa6f4c17245a9bf8777404
Another one liner to remove empty ("" empty string) elements from your array.
$array = array_filter($array, function($a) {return $a !== "";});
Note: This code deliberately keeps null, 0 and false elements.
Or maybe you want to trim your array elements first:
$array = array_filter($array, function($a) {
return trim($a) !== "";
});
Note: This code also removes null and false elements.
If you are working with a numerical array and need to re-index the array after removing empty elements, use the array_values function:
array_values(array_filter($array));
Also see: PHP reindex array?
The most voted answer is wrong or at least not completely true as the OP is talking about blank strings only. Here's a thorough explanation:
What does empty mean?
First of all, we must agree on what empty means. Do you mean to filter out:
the empty strings only ("")?
the strictly false values? ($element === false)
the falsey values? (i.e. 0, 0.0, "", "0", NULL, array()...)
the equivalent of PHP's empty() function?
How do you filter out the values
To filter out empty strings only:
$filtered = array_diff($originalArray, array(""));
To only filter out strictly false values, you must use a callback function:
$filtered = array_diff($originalArray, 'myCallback');
function myCallback($var) {
return $var === false;
}
The callback is also useful for any combination in which you want to filter out the "falsey" values, except some. (For example, filter every null and false, etc, leaving only 0):
$filtered = array_filter($originalArray, 'myCallback');
function myCallback($var) {
return ($var === 0 || $var === '0');
}
Third and fourth case are (for our purposes at last) equivalent, and for that all you have to use is the default:
$filtered = array_filter($originalArray);
$a = array(1, '', '', '', 2, '', 3, 4);
$b = array_values(array_filter($a));
print_r($b)
For multidimensional array
$data = array_map('array_filter', $data);
$data = array_filter($data);
I had to do this in order to keep an array value of (string) 0
$url = array_filter($data, function ($value) {
return (!empty($value) || $value === 0 || $value==='0');
});
$out_array = array_filter($input_array, function($item)
{
return !empty($item['key_of_array_to_check_whether_it_is_empty']);
}
);
function trim_array($Array)
{
foreach ($Array as $value) {
if(trim($value) === '') {
$index = array_search($value, $Array);
unset($Array[$index]);
}
}
return $Array;
}
Just want to contribute an alternative to loops...also addressing gaps in keys...
In my case, I wanted to keep sequential array keys when the operation was complete (not just odd numbers, which is what I was staring at. Setting up code to look just for odd keys seemed fragile to me and not future-friendly.)
I was looking for something more like this: http://gotofritz.net/blog/howto/removing-empty-array-elements-php/
The combination of array_filter and array_slice does the trick.
$example = array_filter($example);
$example = array_slice($example,0);
No idea about efficiencies or benchmarks but it works.
I use the following script to remove empty elements from an array
for ($i=0; $i<$count($Array); $i++)
{
if (empty($Array[$i])) unset($Array[$i]);
}
$my = ("0"=>" ","1"=>"5","2"=>"6","3"=>" ");
foreach ($my as $key => $value) {
if (is_null($value)) unset($my[$key]);
}
foreach ($my as $key => $value) {
echo $key . ':' . $value . '<br>';
}
output
1:5
2:6
foreach($arr as $key => $val){
if (empty($val)) unset($arr[$key];
}
Just one line :
Update (thanks to #suther):
$array_without_empty_values = array_filter($array);
use array_filter function to remove empty values:
$linksArray = array_filter($linksArray);
print_r($linksArray);
Remove empty array elements
function removeEmptyElements(&$element)
{
if (is_array($element)) {
if ($key = key($element)) {
$element[$key] = array_filter($element);
}
if (count($element) != count($element, COUNT_RECURSIVE)) {
$element = array_filter(current($element), __FUNCTION__);
}
return $element;
} else {
return empty($element) ? false : $element;
}
}
$data = array(
'horarios' => array(),
'grupos' => array(
'1A' => array(
'Juan' => array(
'calificaciones' => array(
'Matematicas' => 8,
'Español' => 5,
'Ingles' => 9,
),
'asistencias' => array(
'enero' => 20,
'febrero' => 10,
'marzo' => '',
)
),
'Damian' => array(
'calificaciones' => array(
'Matematicas' => 10,
'Español' => '',
'Ingles' => 9,
),
'asistencias' => array(
'enero' => 20,
'febrero' => '',
'marzo' => 5,
)
),
),
'1B' => array(
'Mariana' => array(
'calificaciones' => array(
'Matematicas' => null,
'Español' => 7,
'Ingles' => 9,
),
'asistencias' => array(
'enero' => null,
'febrero' => 5,
'marzo' => 5,
)
),
),
)
);
$data = array_filter($data, 'removeEmptyElements');
var_dump($data);
¡it works!
As per your method, you can just catch those elements in an another array and use that one like follows,
foreach($linksArray as $link){
if(!empty($link)){
$new_arr[] = $link
}
}
print_r($new_arr);
I think array_walk is much more suitable here
$linksArray = array('name', ' ', ' 342', '0', 0.0, null, '', false);
array_walk($linksArray, function(&$v, $k) use (&$linksArray){
$v = trim($v);
if ($v == '')
unset($linksArray[$k]);
});
print_r($linksArray);
Output:
Array
(
[0] => name
[2] => 342
[3] => 0
[4] => 0
)
We made sure that empty values are removed even if the user adds more than one space
We also trimmed empty spaces from the valid values
Finally, only (null), (Boolean False) and ('') will be considered empty strings
As for False it's ok to remove it, because AFAIK the user can't submit boolean values.
With these types of things, it's much better to be explicit about what you want and do not want.
It will help the next guy to not get caught by surprise at the behaviour of array_filter() without a callback. For example, I ended up on this question because I forgot if array_filter() removes NULL or not. I wasted time when I could have just used the solution below and had my answer.
Also, the logic is language angnostic in the sense that the code can be copied into another language without having to under stand the behaviour of a php function like array_filter when no callback is passed.
In my solution, it is clear at glance as to what is happening. Remove a conditional to keep something or add a new condition to filter additional values.
Disregard the actual use of array_filter() since I am just passing it a custom callback - you could go ahead and extract that out to its own function if you wanted. I am just using it as sugar for a foreach loop.
<?php
$xs = [0, 1, 2, 3, "0", "", false, null];
$xs = array_filter($xs, function($x) {
if ($x === null) { return false; }
if ($x === false) { return false; }
if ($x === "") { return false; }
if ($x === "0") { return false; }
return true;
});
$xs = array_values($xs); // reindex array
echo "<pre>";
var_export($xs);
Another benefit of this approach is that you can break apart the filtering predicates into an abstract function that filters a single value per array and build up to a composable solution.
See this example and the inline comments for the output.
<?php
/**
* #param string $valueToFilter
*
* #return \Closure A function that expects a 1d array and returns an array
* filtered of values matching $valueToFilter.
*/
function filterValue($valueToFilter)
{
return function($xs) use ($valueToFilter) {
return array_filter($xs, function($x) use ($valueToFilter) {
return $x !== $valueToFilter;
});
};
}
// partially applied functions that each expect a 1d array of values
$filterNull = filterValue(null);
$filterFalse = filterValue(false);
$filterZeroString = filterValue("0");
$filterEmptyString = filterValue("");
$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterNull($xs); //=> [0, 1, 2, 3, false, "0", ""]
$xs = $filterFalse($xs); //=> [0, 1, 2, 3, "0", ""]
$xs = $filterZeroString($xs); //=> [0, 1, 2, 3, ""]
$xs = $filterEmptyString($xs); //=> [0, 1, 2, 3]
echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
Now you can dynamically create a function called filterer() using pipe() that will apply these partially applied functions for you.
<?php
/**
* Supply between 1..n functions each with an arity of 1 (that is, accepts
* one and only one argument). Versions prior to php 5.6 do not have the
* variadic operator `...` and as such require the use of `func_get_args()` to
* obtain the comma-delimited list of expressions provided via the argument
* list on function call.
*
* Example - Call the function `pipe()` like:
*
* pipe ($addOne, $multiplyByTwo);
*
* #return closure
*/
function pipe()
{
$functions = func_get_args(); // an array of callable functions [$addOne, $multiplyByTwo]
return function ($initialAccumulator) use ($functions) { // return a function with an arity of 1
return array_reduce( // chain the supplied `$arg` value through each function in the list of functions
$functions, // an array of functions to reduce over the supplied `$arg` value
function ($accumulator, $currFn) { // the reducer (a reducing function)
return $currFn($accumulator);
},
$initialAccumulator
);
};
}
/**
* #param string $valueToFilter
*
* #return \Closure A function that expects a 1d array and returns an array
* filtered of values matching $valueToFilter.
*/
function filterValue($valueToFilter)
{
return function($xs) use ($valueToFilter) {
return array_filter($xs, function($x) use ($valueToFilter) {
return $x !== $valueToFilter;
});
};
}
$filterer = pipe(
filterValue(null),
filterValue(false),
filterValue("0"),
filterValue("")
);
$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterer($xs);
echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
try this **
**Example
$or = array(
'PersonalInformation.first_name' => $this->request->data['User']['first_name'],
'PersonalInformation.last_name' => $this->request->data['User']['last_name'],
'PersonalInformation.primary_phone' => $this->request->data['User']['primary_phone'],
'PersonalInformation.dob' => $this->request->data['User']['dob'],
'User.email' => $this->request->data['User']['email'],
);
$or = array_filter($or);
$condition = array(
'User.role' => array('U', 'P'),
'User.user_status' => array('active', 'lead', 'inactive'),
'OR' => $or
);
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 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);
Some elements in my array are empty strings based on what the user has submitted. I need to remove those elements. I have this:
foreach($linksArray as $link)
{
if($link == '')
{
unset($link);
}
}
print_r($linksArray);
But it doesn't work. $linksArray still has empty elements. I have also tried doing it with the empty() function, but the outcome is the same.
As you're dealing with an array of strings, you can simply use array_filter(), which conveniently handles all this for you:
print_r(array_filter($linksArray));
Keep in mind that if no callback is supplied, all entries of array equal to FALSE (see converting to boolean) will be removed. So if you need to preserve elements that are i.e. exact string '0', you will need a custom callback:
// PHP 7.4 and later
print_r(array_filter($linksArray, fn($value) => !is_null($value) && $value !== ''));
// PHP 5.3 and later
print_r(array_filter($linksArray, function($value) { return !is_null($value) && $value !== ''; }));
// PHP < 5.3
print_r(array_filter($linksArray, create_function('$value', 'return $value !== "";')));
Note: If you need to reindex the array after removing the empty elements, use: $linksArray = array_values(array_filter($linksArray));
You can use array_filter to remove empty elements:
$emptyRemoved = array_filter($linksArray);
If you have (int) 0 in your array, you may use the following:
$emptyRemoved = remove_empty($linksArray);
function remove_empty($array) {
return array_filter($array, '_remove_empty_internal');
}
function _remove_empty_internal($value) {
return !empty($value) || $value === 0;
}
EDIT: Maybe your elements are not empty per se but contain one or more spaces... You can use the following before using array_filter
$trimmedArray = array_map('trim', $linksArray);
The most popular answer on this topic is absolutely INCORRECT.
Consider the following PHP script:
<?php
$arr = array('1', '', '2', '3', '0');
// Incorrect:
print_r(array_filter($arr));
// Correct:
print_r(array_filter($arr, 'strlen'));
Why is this? Because a string containing a single '0' character also evaluates to boolean false, so even though it's not an empty string, it will still get filtered. That would be a bug.
Passing the built-in strlen function as the filtering function will work, because it returns a non-zero integer for a non-empty string, and a zero integer for an empty string. Non-zero integers always evaluate to true when converted to boolean, while zero integers always evaluate to false when converted to boolean.
So, the absolute, definitive, correct answer is:
$arr = array_filter($arr, 'strlen');
$linksArray = array_filter($linksArray);
"If no callback is supplied, all entries of input equal to FALSE will be removed." -- http://php.net/manual/en/function.array-filter.php
$myarray = array_filter($myarray, 'strlen'); //removes null values but leaves "0"
$myarray = array_filter($myarray); //removes all null values
You can just do
array_filter($array)
array_filter: "If no callback is supplied, all entries of input equal to FALSE will be removed." This means that elements with values NULL, 0, '0', '', FALSE, array() will be removed too.
The other option is doing
array_diff($array, array(''))
which will remove elements with values NULL, '' and FALSE.
Hope this helps :)
UPDATE
Here is an example.
$a = array(0, '0', NULL, FALSE, '', array());
var_dump(array_filter($a));
// array()
var_dump(array_diff($a, array(0))) // 0 / '0'
// array(NULL, FALSE, '', array());
var_dump(array_diff($a, array(NULL))) // NULL / FALSE / ''
// array(0, '0', array())
To sum up:
0 or '0' will remove 0 and '0'
NULL, FALSE or '' will remove NULL, FALSE and ''
foreach($linksArray as $key => $link)
{
if($link === '')
{
unset($linksArray[$key]);
}
}
print_r($linksArray);
In short:
This is my suggested code:
$myarray = array_values(array_filter(array_map('trim', $myarray), 'strlen'));
Explanation:
I thinks use array_filter is good, but not enough, because values be like space and \n,... keep in the array and this is usually bad.
So I suggest you use mixture array_filter and array_map.
array_map is for trimming, array_filter is for remove empty values, strlen is for keep 0 value, and array_values is for re indexing if you needed.
Samples:
$myarray = array("\r", "\n", "\r\n", "", " ", "0", "a");
// "\r", "\n", "\r\n", " ", "a"
$new1 = array_filter($myarray);
// "a"
$new2 = array_filter(array_map('trim', $myarray));
// "0", "a"
$new3 = array_filter(array_map('trim', $myarray), 'strlen');
// "0", "a" (reindex)
$new4 = array_values(array_filter(array_map('trim', $myarray), 'strlen'));
var_dump($new1, $new2, $new3, $new4);
Results:
array(5) {
[0]=>
" string(1) "
[1]=>
string(1) "
"
[2]=>
string(2) "
"
[4]=>
string(1) " "
[6]=>
string(1) "a"
}
array(1) {
[6]=>
string(1) "a"
}
array(2) {
[5]=>
string(1) "0"
[6]=>
string(1) "a"
}
array(2) {
[0]=>
string(1) "0"
[1]=>
string(1) "a"
}
Online Test:
http://sandbox.onlinephpfunctions.com/code/e02f5d8795938be9f0fa6f4c17245a9bf8777404
Another one liner to remove empty ("" empty string) elements from your array.
$array = array_filter($array, function($a) {return $a !== "";});
Note: This code deliberately keeps null, 0 and false elements.
Or maybe you want to trim your array elements first:
$array = array_filter($array, function($a) {
return trim($a) !== "";
});
Note: This code also removes null and false elements.
If you are working with a numerical array and need to re-index the array after removing empty elements, use the array_values function:
array_values(array_filter($array));
Also see: PHP reindex array?
The most voted answer is wrong or at least not completely true as the OP is talking about blank strings only. Here's a thorough explanation:
What does empty mean?
First of all, we must agree on what empty means. Do you mean to filter out:
the empty strings only ("")?
the strictly false values? ($element === false)
the falsey values? (i.e. 0, 0.0, "", "0", NULL, array()...)
the equivalent of PHP's empty() function?
How do you filter out the values
To filter out empty strings only:
$filtered = array_diff($originalArray, array(""));
To only filter out strictly false values, you must use a callback function:
$filtered = array_diff($originalArray, 'myCallback');
function myCallback($var) {
return $var === false;
}
The callback is also useful for any combination in which you want to filter out the "falsey" values, except some. (For example, filter every null and false, etc, leaving only 0):
$filtered = array_filter($originalArray, 'myCallback');
function myCallback($var) {
return ($var === 0 || $var === '0');
}
Third and fourth case are (for our purposes at last) equivalent, and for that all you have to use is the default:
$filtered = array_filter($originalArray);
$a = array(1, '', '', '', 2, '', 3, 4);
$b = array_values(array_filter($a));
print_r($b)
For multidimensional array
$data = array_map('array_filter', $data);
$data = array_filter($data);
I had to do this in order to keep an array value of (string) 0
$url = array_filter($data, function ($value) {
return (!empty($value) || $value === 0 || $value==='0');
});
$out_array = array_filter($input_array, function($item)
{
return !empty($item['key_of_array_to_check_whether_it_is_empty']);
}
);
function trim_array($Array)
{
foreach ($Array as $value) {
if(trim($value) === '') {
$index = array_search($value, $Array);
unset($Array[$index]);
}
}
return $Array;
}
Just want to contribute an alternative to loops...also addressing gaps in keys...
In my case, I wanted to keep sequential array keys when the operation was complete (not just odd numbers, which is what I was staring at. Setting up code to look just for odd keys seemed fragile to me and not future-friendly.)
I was looking for something more like this: http://gotofritz.net/blog/howto/removing-empty-array-elements-php/
The combination of array_filter and array_slice does the trick.
$example = array_filter($example);
$example = array_slice($example,0);
No idea about efficiencies or benchmarks but it works.
I use the following script to remove empty elements from an array
for ($i=0; $i<$count($Array); $i++)
{
if (empty($Array[$i])) unset($Array[$i]);
}
$my = ("0"=>" ","1"=>"5","2"=>"6","3"=>" ");
foreach ($my as $key => $value) {
if (is_null($value)) unset($my[$key]);
}
foreach ($my as $key => $value) {
echo $key . ':' . $value . '<br>';
}
output
1:5
2:6
foreach($arr as $key => $val){
if (empty($val)) unset($arr[$key];
}
Just one line :
Update (thanks to #suther):
$array_without_empty_values = array_filter($array);
use array_filter function to remove empty values:
$linksArray = array_filter($linksArray);
print_r($linksArray);
Remove empty array elements
function removeEmptyElements(&$element)
{
if (is_array($element)) {
if ($key = key($element)) {
$element[$key] = array_filter($element);
}
if (count($element) != count($element, COUNT_RECURSIVE)) {
$element = array_filter(current($element), __FUNCTION__);
}
return $element;
} else {
return empty($element) ? false : $element;
}
}
$data = array(
'horarios' => array(),
'grupos' => array(
'1A' => array(
'Juan' => array(
'calificaciones' => array(
'Matematicas' => 8,
'Español' => 5,
'Ingles' => 9,
),
'asistencias' => array(
'enero' => 20,
'febrero' => 10,
'marzo' => '',
)
),
'Damian' => array(
'calificaciones' => array(
'Matematicas' => 10,
'Español' => '',
'Ingles' => 9,
),
'asistencias' => array(
'enero' => 20,
'febrero' => '',
'marzo' => 5,
)
),
),
'1B' => array(
'Mariana' => array(
'calificaciones' => array(
'Matematicas' => null,
'Español' => 7,
'Ingles' => 9,
),
'asistencias' => array(
'enero' => null,
'febrero' => 5,
'marzo' => 5,
)
),
),
)
);
$data = array_filter($data, 'removeEmptyElements');
var_dump($data);
¡it works!
As per your method, you can just catch those elements in an another array and use that one like follows,
foreach($linksArray as $link){
if(!empty($link)){
$new_arr[] = $link
}
}
print_r($new_arr);
I think array_walk is much more suitable here
$linksArray = array('name', ' ', ' 342', '0', 0.0, null, '', false);
array_walk($linksArray, function(&$v, $k) use (&$linksArray){
$v = trim($v);
if ($v == '')
unset($linksArray[$k]);
});
print_r($linksArray);
Output:
Array
(
[0] => name
[2] => 342
[3] => 0
[4] => 0
)
We made sure that empty values are removed even if the user adds more than one space
We also trimmed empty spaces from the valid values
Finally, only (null), (Boolean False) and ('') will be considered empty strings
As for False it's ok to remove it, because AFAIK the user can't submit boolean values.
With these types of things, it's much better to be explicit about what you want and do not want.
It will help the next guy to not get caught by surprise at the behaviour of array_filter() without a callback. For example, I ended up on this question because I forgot if array_filter() removes NULL or not. I wasted time when I could have just used the solution below and had my answer.
Also, the logic is language angnostic in the sense that the code can be copied into another language without having to under stand the behaviour of a php function like array_filter when no callback is passed.
In my solution, it is clear at glance as to what is happening. Remove a conditional to keep something or add a new condition to filter additional values.
Disregard the actual use of array_filter() since I am just passing it a custom callback - you could go ahead and extract that out to its own function if you wanted. I am just using it as sugar for a foreach loop.
<?php
$xs = [0, 1, 2, 3, "0", "", false, null];
$xs = array_filter($xs, function($x) {
if ($x === null) { return false; }
if ($x === false) { return false; }
if ($x === "") { return false; }
if ($x === "0") { return false; }
return true;
});
$xs = array_values($xs); // reindex array
echo "<pre>";
var_export($xs);
Another benefit of this approach is that you can break apart the filtering predicates into an abstract function that filters a single value per array and build up to a composable solution.
See this example and the inline comments for the output.
<?php
/**
* #param string $valueToFilter
*
* #return \Closure A function that expects a 1d array and returns an array
* filtered of values matching $valueToFilter.
*/
function filterValue($valueToFilter)
{
return function($xs) use ($valueToFilter) {
return array_filter($xs, function($x) use ($valueToFilter) {
return $x !== $valueToFilter;
});
};
}
// partially applied functions that each expect a 1d array of values
$filterNull = filterValue(null);
$filterFalse = filterValue(false);
$filterZeroString = filterValue("0");
$filterEmptyString = filterValue("");
$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterNull($xs); //=> [0, 1, 2, 3, false, "0", ""]
$xs = $filterFalse($xs); //=> [0, 1, 2, 3, "0", ""]
$xs = $filterZeroString($xs); //=> [0, 1, 2, 3, ""]
$xs = $filterEmptyString($xs); //=> [0, 1, 2, 3]
echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
Now you can dynamically create a function called filterer() using pipe() that will apply these partially applied functions for you.
<?php
/**
* Supply between 1..n functions each with an arity of 1 (that is, accepts
* one and only one argument). Versions prior to php 5.6 do not have the
* variadic operator `...` and as such require the use of `func_get_args()` to
* obtain the comma-delimited list of expressions provided via the argument
* list on function call.
*
* Example - Call the function `pipe()` like:
*
* pipe ($addOne, $multiplyByTwo);
*
* #return closure
*/
function pipe()
{
$functions = func_get_args(); // an array of callable functions [$addOne, $multiplyByTwo]
return function ($initialAccumulator) use ($functions) { // return a function with an arity of 1
return array_reduce( // chain the supplied `$arg` value through each function in the list of functions
$functions, // an array of functions to reduce over the supplied `$arg` value
function ($accumulator, $currFn) { // the reducer (a reducing function)
return $currFn($accumulator);
},
$initialAccumulator
);
};
}
/**
* #param string $valueToFilter
*
* #return \Closure A function that expects a 1d array and returns an array
* filtered of values matching $valueToFilter.
*/
function filterValue($valueToFilter)
{
return function($xs) use ($valueToFilter) {
return array_filter($xs, function($x) use ($valueToFilter) {
return $x !== $valueToFilter;
});
};
}
$filterer = pipe(
filterValue(null),
filterValue(false),
filterValue("0"),
filterValue("")
);
$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterer($xs);
echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
try this **
**Example
$or = array(
'PersonalInformation.first_name' => $this->request->data['User']['first_name'],
'PersonalInformation.last_name' => $this->request->data['User']['last_name'],
'PersonalInformation.primary_phone' => $this->request->data['User']['primary_phone'],
'PersonalInformation.dob' => $this->request->data['User']['dob'],
'User.email' => $this->request->data['User']['email'],
);
$or = array_filter($or);
$condition = array(
'User.role' => array('U', 'P'),
'User.user_status' => array('active', 'lead', 'inactive'),
'OR' => $or
);