array_filter

(PHP 4 >= 4.0.6, PHP 5)

array_filter --  用回调函数过滤数组中的单元

说明

array array_filter ( array input [, callback callback] )

array_filter() 依次将 input 数组中的每个值传递到 callback 函数。如果 callback 函数返回 TRUE,则 input 数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。

例子 1. array_filter() 例子

<?php
function odd($var)
{
    return(
$var % 2 == 1);
}

function
even($var)
{
    return(
$var % 2 == 0);
}

$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);

echo
"Odd :\n";
print_r(array_filter($array1, "odd"));
echo
"Even:\n";
print_r(array_filter($array2, "even"));
?>

上例将输出:

Odd :
Array
(
    [a] => 1
    [c] => 3
    [e] => 5
)
Even:
Array
(
    [0] => 6
    [2] => 8
    [4] => 10
    [6] => 12
)

用户不应在回调函数中修改数组本身。例如增加/删除单元或者对 array_filter() 正在作用的数组进行 unset。如果数组改变了,此函数的行为没有定义。

如果没有提供 callback 函数,array_filter() 将删除 input 中所有等值为 FALSE 的条目。更多信息见转换为布尔值

例子 2. array_filter()callback

<?php

$entry
= array(
             
0 => 'foo',
             
1 => false,
             
2 => -1,
             
3 => null,
             
4 => ''
          
);

print_r(array_filter($entry));
?>

上例将输出:

Array
(
    [0] => foo
    [2] => -1
)

参见 array_map()array_reduce()array_walk()


add a note add a note User Contributed Notes
klaproth at creative-mindworks dot de
23-Oct-2006 10:13
As long as the array's keys are irrelevant, there is a simple way to remove blank values from the array, after filtering has been applied. The following example is used to remove all strings from an array that have a length of less than 4 characters.

<?php
function validElement($element) {
   return
strlen($element) > 3;
}

$filtered_array = array_values(array_filter($input_array, "validElement"));
?>
Fladnag - bahatest at ifrance dot com
23-Oct-2006 12:19
If you have a form with multiple checkbox having ID element as value for selection in a list, you probably have a SQL request like :
$req="SELECT ... WHERE ID IN (".implode(',', array_keys($choices)).")";
without quote before and after choices keys because they are numeric values... but in fact, they can be string values, and a SQL injection problem.

with array_filter, you can easily filter bad values :
<?php
   $choices
=array('A'=>'on', -1=>'on', 0=>'on', 1=>'on', 12=>'on', "1)or 1=1--"=>'on');
  
print_r($choices);
  
$choices=array_filter(array_keys($choices), 'is_numeric');
  
print_r($choices);
?>
will print :
<?php
Array
(
   [
A] => on
  
[-1] => on
  
[0] => on
  
[1] => on
  
[12] => on
  
[1)or 1=1--] => on
)
Array
(
   [
1] => -1
  
[2] => 0
  
[3] => 1
  
[4] => 12
)
?>
ydotzhangatwriwindberdotorg
18-Jan-2006 05:57
I have written a function that will filter an array by the frequency of
element value in the array.  This may be useful to some people.

/////////////////////////////////////////////////////////////////
//    Filter an array by value freguebcy
//    Input: $array
//    cut-off: $frequency (>=1)
//    result option option: 1=$frequency and higher
//          0=$frequency only
//          -1=$frequency and lower
/////////////////////////////////////////////////////////////////
function filter_array($array, $frequency = 2, $include = 1){
   $freg = array_count_values($array);
   if($frequency<1){
       print "** frequency cut-off should be >= 1! **\n";
       return false;
   }
   foreach($freg as $k => $v){
       if($include == 0){
           if($frequency != $v){
               $freg[$k] = 0;
           }
       }elseif($include > 0){
           if($frequency > $v){
               $freg[$k] = 0;
           }
       }else{
           if($frequency < $v){
               $freg[$k] = 0;
           }
       }
   }
   $filtered = array_filter($freg);
   $values = array_keys($filtered);
   return array_intersect($array,$values);
}
xert
26-Apr-2005 08:14
According to a simple test with array_filter($array) and array_diff($array, array('')) is array_filter 2.5 times faster than array_diff when deleting empty entries.
timo at frenay dot net
04-Jan-2005 04:38
Do not use this function to delete known values from an array; array_diff() does the job much easier.
For example, to delete all empty strings from an array:

<?php
   $arr
= array_diff($arr, array(''));
?>
marc dot vanwoerkom at fernuni-hagen dot de
05-Jul-2004 11:09
Some of PHP's array functions play a prominent role in so called functional programming languages, where they show up under a slightly different name:

<?php
  array_filter
() -> filter(),
 
array_map() -> map(),
 
array_reduce() -> foldl() ("fold left")
?>

Functional programming is a paradigm which centers around the side-effect free evaluation of functions. A program execution is a call of a function, which in turn might be defined by many other functions. One idea is to use functions to create special purpose functions from other functions.

The array functions mentioned above allow you compose new functions on arrays.

E.g. array_sum = array_map("sum", $arr).

This leads to a style of programming that looks much like algebra, e.g. the Bird/Meertens formalism.

E.g. a mathematician might state

  map(f o g) = map(f) o map(g)

the so called "loop fusion" law.

Many functions on arrays can be created by the use of the foldr() function (which works like foldl, but eating up array elements from the right).

I can't get into detail here, I just wanted to provide a hint about where this stuff also shows up and the theory behind it.
Maxwel Leite
11-May-2004 11:17
For any type of array. Basead in redshift code.

<?php
function array_clean ($array, $todelete = false, $caseSensitive = false) {
   foreach(
$array as $key => $value) {
       if(
is_array($value)) {
          
$array[$key] = array_clean($array[$key], $todelete, $caseSensitive);
       }
       else {
           if(
$todelete) {
               if(
$caseSensitive) {
                   if(
strstr($value ,$todelete) !== false)
                       unset(
$array[$key]);
               }
               else {
                   if(
stristr($value, $todelete) !== false)
                       unset(
$array[$key]);
               }
           }
           elseif (empty(
$value)) {
               unset(
$array[$key]);
           }
       }
   }
   return
$array;
}
?>
steven at xinu dot org
23-Feb-2004 04:39
The anonymous fellow a few posts up was trying to illustrate how to use the array_filter() function with class methods but confused things a bit. Here's a cleaner example:

<?php
class testclass
{
   function
testclass()
   {
      
// define the numbers array
      
$numbers = array(1, 2, 3, 4, 5, 6);

      
// pull out the odd numbers
      
$odd = array_filter($numbers, array($this, "odd"));

      
// pull out the even numbers
      
$even = array_filter($numbers, array($this, "even"));
   }

   function
odd($var)
   {
       return(
$var % 2 == 1);
   }

   function
even($var)
   {
       return(
$var % 2 == 0);
   }
}
?>
Jeremy
30-Dec-2003 05:31
Here is a nice little function which will apply a callback function recursively over a multidimensional array. If the callback function returns false, then it replaces the value of the array with $filtered_ouput. This function gracefully handles objects inside of arrays (and objects within objects within arrays, etc). It is specifically designed for your callback function to process on the array key's (unlike normal array_filter which filters on the values), but it could work on the array values depending on your test criteria (YMMV).

<?PHP

function array_key_filter_multi($array, $callback, $filtered_output = "")
{
  
$ret = array();
   foreach(
$array as $key=>$value) {
       if(
$callback($key,$value)) {
           if(
is_array($value)) {
              
$ret[$key] = array_key_filter_multi($value, $callback, $filtered_output);
           }
           elseif(
is_object($value)) {
              
$ret[$key] = array_key_filter_multi(get_object_vars($value), $callback, $filtered_output);
           }
           else {   
              
$ret[$key]=$value;
           }
       }
       else {
          
$ret[$key]=$filtered_output;
       }
   }
   return
$ret;
}

?>

We use this to filter redundant data from debugging output. An example usage is:

<?

$callback_func
= create_function('$key, $value', 'return ($key == "db" || $key == "smarty") ? false : true;');
echo
"<PRE>" . print_r(array_key_filter_multi($_SESSION, $callback_func, "**filtered by function**"), true) . "</PRE>";

?>

Which filters all keys with "db" or "smarty" as their name (including objects which have a reference to those variables). The output of the above in a test case I did is the following:

Array
(
   [userdata] => Array
       (
           [sid] => a130e675d380e0e9fe47897922d719ac
           [not_in_db] =>
           [user_id] => 1
           [session_id] => 154
           [permissions] => 1
           [username] => tester
       )
   [systemobjects] => Array
       (
           [db] => **filtered by function**
           [smarty] => **filtered by function**
       )
)
redshift at pandora dot be
29-Jun-2003 03:01
Hi all,
Here's a function that will look trough an array, and removes the array member when the search string is found.

<?php
function array_clean ($input, $delete = false, $caseSensitive = false)
   {
  
$i = 0;
   while(
$i < count($input))
       {
       if(
$delete)
           {
           if(
$caseSensitive)
               {
               if(!
strstr($input[$i] ,$delete))
                   {
                  
$return[] = $input[$i];
                   }
               }
               else
               {
               if(!
stristr($input[$i], $delete))
                   {
                  
$return[] = $input[$i];
                   }
               }
           }
           else
           {
           if(!empty(
$input[$i]))
               {
              
$return[] = $input[$i];
               }
           }
      
$i++;
       }
   return
$return;
   }
?>

array array_clean(array input [, string needle [, boolean case sensitive]])

if needle is left empty, the function will delete the array members that have no value (this means if it's empty).
NOTE: It rebuilds the array from scratch, so keys begin with 0, like you would create a new array.

Example:
$array = array("John", "Doe", "Macy");
$array = array_clean($array, "doe", false);

print_r($array);
would return:
array
(
   [0] => John
   [1] => Macy
)

Hopes this helps someone :-)
skd2 at ece dot msstate dot edu
15-May-2003 06:24
The following function modifies the supplied array recursively so that filtering is performed on multidimentional arrays as well, while preserving keys.

<?php
function array_cleanse(&$arr){

$temp = array();
reset($arr);
if(
count($arr) == 0) return "";

foreach(
$arr as $key=>$val):

 (
is_array($val))? array_cleanse($val) : NULL;
 (
$val)? $temp[$key] = $val : NULL;

endforeach;

$arr = $temp;
reset($arr);
}
?>

$arr1 = array('a'=>20,'b'=>array(''),'c'=>array(1,0,2),'d'=>0);
array_cleanse($arr1);
$arr1 will be array('a'=>20,'c'=>array(1,2))

array_filter may not be used as it does not modify the array within itself.
12-Feb-2003 06:47
You cannot do this:
$non_empty_array = array_filter($original_array, 'empty');
Since empty() is not a function but a language construct. (http://www.php.net/manual/en/function.empty.php)
ajohnson at speakeasy dot org
28-Sep-2002 03:42
be careful with the above function "array_delete"'s use of the stristr function, it could be slightly misleading. consider the following:

<?php
function array_delete($array, $filterforsubstring){
  
$thisarray = array ();
   foreach(
$array as $value)
       if(
stristr($value, $filterforsubstring)===false && strlen($value)>0)
          
$thisarray[] = $value;
   return
$thisarray;
}

function
array_delete2($array, $filterforstring, $removeblanksflag=0){
  
$thisarray = array ();
   foreach(
$array as $value)
       if(!(
stristr($value, $filterforstring) && strlen($value)==strlen($filterforstring))
               && !(
strlen($value)==0 && $removeblanksflag))
          
$thisarray[] = $value;
   return
$thisarray;
}

function
array_delete3($array, $filterfor, $substringflag=0, $removeblanksflag=0){
  
$thisarray = array ();
   foreach(
$array as $value)
       if(
           !(
stristr($value, $filterfor)
               && (
$substringflag || strlen($value)==strlen($filterfor))
           )
           && !(
strlen($value)==0 && $removeblanksflag)
       )
          
$thisarray[] = $value;
   return
$thisarray;
}

$array1 = array ('the OtHeR thang','this', 'that', 'OtHer','', 9, 101, 'fifty', ' oTher', 'otHer ','','other','Other','','other blank things');

echo
"<pre>array :\n";
print_r($array1);

$array2=array_delete($array1, "Other");

echo
"array_delete(\$array1, \"Other\"):\n";
print_r($array2);

$array2=array_delete2($array1, "Other");

echo
"array_delete2(\$array1, \"Other\"):\n";
print_r($array2);

$array2=array_delete2($array1, "Other",1);

echo
"array_delete2(\$array1, \"Other\",1):\n";
print_r($array2);

$array2=array_delete3($array1, "Other",1);

echo
"array_delete3(\$array1, \"Other\",1):\n";
print_r($array2);

$array2=array_delete3($array1, "Other",0,1);

echo
"array_delete3(\$array1, \"Other\",0,1):\n";
print_r($array2);
 
?>
ajohnson at speakeasy dot org
18-Aug-2002 04:04
I was looking for a function to delete values from an array and thought I had found it in array_filter(), however, I *didn't* want the keys to be preserved *and* I needed blank values cleaned out of the array as well. I came up with the following (with help from many of the above examples):

<?php
function array_delete($array, $filterfor){
 
$thisarray = array ();
  foreach(
$array as $value)
   if(
stristr($value, $filterfor)===false && strlen($value)>0)
    
$thisarray[] = $value;
  return
$thisarray;
}

$array1 = array ('OtHeR','this', 'that', 'Other','', 9, 101, 'fifty', 'other','','');

echo
"<pre>array :\n";
print_r($array1);

$array2=array_delete($array1, "Other");

echo
"filtered:\n";
print_r($array2);
?>
13-Jun-2002 07:14
I was looking for a function able to take some values out of an array iteratively, and found array_filter very useful although i had some trouble figuring out the proper syntax...

class someclass {
   var $current;

   /** this is our iterative function */
   function main ($variable,$array){
       if (end test){
           return true;
       }
       $variable= some treatment...
       if (in_array($variable, $array)){
             $this->current=something...($variable);
           // this is the not-well-documented part
           $array=$array_filter($array, array($this, "array_reduce");
       }
       $this->main($variable, $array);
   }
  
   /** this is the function used to filter */
   function reduce_list($var){
       return ($var!=$this->current);
   }
}
sam,pointsystems,com
21-Feb-2002 09:12
Here's a good function to filter multidimensional arrays:

<?php
function array_filter_multi($input, $filter="", $keepMatches=true) {
       if (!
is_array($input))
               return (
$input==$filter xor $keepMatches==false) ? $input : false;
       while (list (
$key,$value) = @each($input)){
              
$res = array_filter_multi($value, $filter,$keepMatches);
               if (
$res !== false)
                      
$out[$key] = $res;
       }
       return
$out;
}
?>

Default behavior is to remove blanks from a multi-dimensional array, but you can filter out any string (arg #2) with a positive or negative filter (arg #3).