文字

array_filter

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

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

说明

array array_filter ( array $input [, callable $callback = "" ] )

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

参数

input

要循环的数组

callback

使用的回调函数

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

返回值

返回过滤后的数组。

范例

Example #1 array_filter() 例子

<?php
function  odd ( $var )
{
    
// returns whether the input integer is odd
    
return( $var  1 );
}

function 
even ( $var )
{
    
// returns whether the input integer is even
    
return(!( $var  1 ));
}

$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
)

Example #2 array_filter() callback

<?php

$entry 
= array(
             
=>  'foo' ,
             
=>  false ,
             
=> - 1 ,
             
=>  null ,
             
=>  ''
          
);

print_r ( array_filter ( $entry ));
?>

以上例程会输出:

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

注释

Caution

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

参见

  • array_map() - 将回调函数作用到给定数组的单元上
  • array_reduce() - 用回调函数迭代地将数组简化为单一的值
  • array_walk() - 使用用户自定义函数对数组中的每个元素做回调处理

用户评论:

[#1] josephyala at gmail dot com [2015-10-17 21:37:40]

Dose this has a good look?

<?php
class FP{
public 
$result;
public function 
info($data) {
$a = function($data)
{
return 
$data;
};
$this->result $a($data);
return 
$this->result;
}
}
$obj = new FP();
echo 
$obj->info("I will like to go to the university for studies");
?>

[#2] yuzhen huang [2015-05-16 13:49:38]

from php  5.3,  we use anonymous function as second argument:

$a = array('a'=>1, 'b'=>2, 'c'=>false, 'd'=>0);
$b = array_filter($a, function($v){return $v !== 0;});
var_dump($b);

output:
array(3) {
  'a' =>
  int(1)
  'b' =>
  int(2)
  'c' =>
  bool(false)
}

[#3] njt1982 at yahoo dot com [2015-04-30 13:18:25]

If you have an array of KV pairs and you want all the items where a value is X, you dont need to make a callback for array_filter. You can use array_intersect:

<?php
print_r
(array_intersect(
  array(
    
'a' => 1,
    
'b' => 1,
    
'c' => 1,
    
'd' => 2,
    
'e' => 2,
    
'f' => 2,
  ),
  array(
1)
));

Array
(
    [
a] => 1
    
[b] => 1
    
[c] => 1
)
?>


The advantage of this approach is you can pass variables into the second array without needing to worry about variable scope and function parameters for array_filter.

[#4] manuelworks at gmail dot com [2015-04-16 15:34:18]

I needed to get the complete array element of a multilevel array where the values of some elements where 'x' or 'y'. Kind of a WHERE  AND in a MySQL Query..

SO if you need to filter an array where 'X' = Y and 'a' = b, here you go.

<?php
 
function getArrayElement($array$indexs$justvalsplease false){
    
$newarray false;
    
//verificamos el array
    
if(is_array($array) && count($array)>0){
        
        
//verify indexs and get # of indexs
        
if(is_array($indexs) && count($indexs)>0$ninds count($indexs);
        else return 
false;
        
        
//search for coincidences
        
foreach(array_keys($array) as $key){

            
//index value coincidence counter. 
            
$count 0;
            
            
//for each index we search            
            
foreach($indexs as $indx => $val){
                
                
//if index value is equal then counts
                
if($array[$key][$indx] == $val){ 
                    
$count++;
                } 
            }
            
//if indexes match, we get the array elements :)
            
if($count == $ninds){
                
                
//if you only need the vals of the first coincidence
                //witch was my case by the way...
                
if($justvalsplease) return $array[$key];
                else 
$newarray[$key] = $array[$key];
            }
        } 
    } 
  return 
$newarray
}
?>



<?php
   
//array
    
$array = array( => array('index1'  => 'a''index2' => 'b''value' => 'hello'),
                  
=> array('index1'  => 'a''index2' => 'c''value' => 'bye'), 
                  
=> array('index1'  => 'b''index2' => 'a''value' => 'hi')); 

    
//indexes
    
$indexs = array('index1' => 'a''index2'=>'b');

    
//aaand we get the element we want.
    
$element getArrayElement($array$indexs);

        
print_r($element);

    

    
Array
    (
        [
0] => Array
            (
                [
index1] => a
                
[index2] => b
                
[value] => hello
            
)
    
    )
?>


IF you want only the array inside the elements just set $justvalsplease true like this
<?php
     $element 
getArrayElement($array$indexs,true);
?>


And you will get just the element content
<?php 
Array
(
    [
index1] => a
    
[index2] => b
    
[value] => hello
)
?>

[#5] no at mail dot com [2015-02-26 15:34:38]

Infinite shame on PHP that array_filter does not transparently work for both arrays and associative arrays. Why in the name of god an array and an associative array return both the same type ?. Unfortunately I can't decide the language to program in otherwise I would move to a more consistent language.

[#6] robbieaverill at gmail dot com [2015-01-21 22:32:37]

If you want to use array_filter with a class method as the callback, you can use a psuedo type callback like this:

<?php
class Test
{
    public function 
doFilter($array)
    {
        return 
array_filter($array, array($this'callbackMethodName'));
    }

    protected function 
callbackMethodName($element)
    {
        return 
$element === 0;
    }
}

$example = new Test;
print_r($example->doFilter(range(110)));
?>


Will return even numbers.

[#7] iancudanielc () gmail ! com [2015-01-09 08:56:03]

If you want to pass the key to the callback function before PHP 5.6.0 (when the flag parameter wasn't implemented):

<?php

$result 
array_filter(array_keys($array), 'is_int');

?>

[#8] m dot abbasian at outlook dot com [2014-10-18 08:58:44]

If you want a quick way to Find Numbers ( remove NULL, FALSE and Empty Strings (""), all Strings) but leave values of 0 (zero)
eg:
<?php


$result array_filter( array( "0",0,1,2,3,'text' ) , 'is_numeric' );

var_dump($result);

?>

[#9] manwe at inversion dot pl [2014-09-21 12:33:18]

array_filter remove also FALSE and 0. To remove only NULL's use:

$af = [1, 0, 2, null, 3, 6, 7];

function is_not_null($val){
return !is_null($val);
}
$af = array_filter($af, 'is_not_null');

[#10] marc dot gray at gmail dot com [2014-04-29 10:44:43]

My favourite use of this function is converting a string to an array, trimming each line and removing empty lines:

<?php
$array 
array_filter(array_map('trim'explode("\n"$string)), 'strlen');
?>


Although it states clearly that array keys are preserved, it's important to note this includes numerically indexed arrays. You can't use a for loop on $array above without processing it through array_values() first.

[#11] Anonymous [2014-04-02 10:26:30]

<?php
function arrayFilter($input$callback null) {
    foreach(
$input as $key => &$value) {
        if(
is_array($value)) {
            
$value arrayFilter($value$callback);
            if(
is_array($value)) {
                if((bool)
$value === false) unset($input[$key]);
            }
            else {
                if((bool)(
$callback $callback($value) : $value) === false) unset($input[$key]);
            }
        }
        else {
            if((bool)(
$callback $callback($value) : $value) === false) unset($input[$key]);
        }
    }
    return 
$input;
}
?>

[#12] avl [2013-11-04 00:25:45]

nice trick:

$array_out = array_filter($array_in, function($var) use($array_other) {
     return in_array($var, $array_other) ? true : false;
});

[#13] qeremy [atta] gmail [dotta] com [2013-10-02 15:12:02]

Here is key-passed array_filter function.

<?php
function arrayfilter(array $array, callable $callback null) {
    if (
$callback == null) {
        
$callback = function($key$val) {
            return (bool) 
$val;
        };
    }
    
$return = array();
    foreach (
$array as $key => $val) {
        if (
$callback($key$val)) {
            
$return[$key] = $val;
        }
    }
    return 
$return;
}

$test_array = array('foo''a' => 'the a''b' => 'the b'11 => 1101''nullfalse0);

$array arrayfilter($test_array, function($key$val) {
   return 
is_string($key);
});
print_r($array);


$array arrayfilter($test_array);
print_r($array);

?>

[#14] tomasz at trejderowski dot pl [2013-09-24 08:16:18]

Read "callback" parameter note with understanding (as well as "converting to boolean" chapter). Keep in midn, that 0, both:

* integer: 0 and
* float: 0.00

evaluates to boolean FALSE! And therefore all array nodes, that have such value WILL ALSO BE FILTERED by array_filter(), with default call back. Unless you provide your own callback function, that will (for example) filter only empty strings and NULLs, but leave "zeros" untouched.

Some people (including me) might be surprised to find this out.

[#15] keksnicoh at googlemail dot com [2013-08-12 11:01:26]

Usefull invertation of array_filter
<?php
$data 
= array(...)
$noArrayData array_filter_inverse($data'is_array');


function array_filter_inverse(array $data, callable $f)
{
    return 
array_filter($data, function() use(&$f) {
        return ! 
call_user_func_array($ffunc_get_args());
    });
}
?>

[#16] pavian at gmail dot com [2013-07-25 10:04:33]

Regarding to strlen() related notes, if you want to filter NULL, FALSE and empty strings from the array, just omit callback function, it does the same trick (but easier).
<?php 

  $clean 
array_filter($array);

?>

[#17] Alix Axel [2013-05-10 12:56:40]

If you need this function to return falsy results (like "0"), yet discard truly empty ones (that have a 0 string length, like null, false, ''), you can use strlen() as the callback:

<?php
array_filter
($array'strlen');
?>

[#18] espertalhao04 at hotmail dot com [2013-04-05 11:58:52]

breich at reich-consulting dot net  made an awesome function, but it has a poor performance, and is bloated.

here is a shorter version:
<?php
function array_remove_keys($array$keys = array(), $callback=null) { 
    if(empty(
$array) || (! is_array($array))) { 
        return 
$array
    } 

    if(
is_string($keys) && !is_array($keys=explode(',',$keys)))
    {
        return 
$array;
    }
    
    foreach(
$keys as $key) {
        
$key=trim($key,' ');
        if(!
$callback || !$callback($array[$key],$key))
            unset(
$array[$key]);
    } 
    return 
$array
}
?>


i decided to let here stay 2 conditions, even though they can be rewritten to 1.

unsetting is faster than array_diff_keys.

sometimes, people separate strings like 'a, b, c' or 'a , b , c'...

i added support for those, since they are essentially the same list.

i also added a callback option, which you specify a function and it will give the value and the key to it.

p.s.: php uses short-circuit evaluation. example:
!$callback || !$callback($array[$key],$key)

if $callback is empty, it doesn't try to run $callback().
why?
because !$callback || !$callback($array[$key],$key) will be true, no matter the value of !$callback().
so, to save resources and time, php jumps if !$callback is true

[#19] g dot kuizinas at anuary dot com [2013-03-26 11:10:55]

<?php
function array_filter_recursive ($data) {
    
$original $data;

    
$data array_filter($data);
    
    
$data array_map(function ($e) {
        return 
is_array($e) ? array_filter_recursive($e) : $e;
    }, 
$data);

    return 
$original === $data $data array_filter_recursive($data);
}

$data = ['a' => 0'b' => [], 'c' => [[]], 'd' => [[[[]]]], 'e' => 'foo''f' => [[['a']]], [true], [[],['a'], [truefalse]]];

$data array_filter_recursive($data);
?>

[#20] tx at tshwarelo-leaka dot co dot za [2013-03-26 09:26:48]

To get rid of all white space in an array without looping.
<?php
   $array 
= array(5"   "2NULL13""7"\n"4"\t");
   
print_r($array);
   
$result array_filter($arraycreate_function('$a','return preg_match("#\S#", $a);'));                 
   
print_r($result);
?>

Array
(
    [0] => 5
    [1] =>    
    [2] => 2
    [3] => 
    [4] => 13
    [5] => 
    [6] => 7
    [7] => 

    [8] => 4
    [9] => 
)
Array
(
    [0] => 5
    [2] => 2
    [4] => 13
    [6] => 7
    [8] => 4
)

[#21] Anonymous [2013-01-13 17:52:07]

If you want a quick way to remove NULL, FALSE and Empty Strings (""), but leave values of 0 (zero), you can use the standard php function strlen as the callback function:
eg:
<?php

// removes all NULL, FALSE and Empty Strings but leaves 0 (zero) values
$result array_filter$array'strlen' );

?>

[#22] jtreminio at gmail dot com [2012-10-04 19:11:23]

You can use array_filter from within a class to access a protected method from that same class:

<?php

class Bar {
    public function 
foo()
    {
        
$array1 = array("a"=>1"b"=>2"c"=>3"d"=>4"e"=>5);

        
print_r(array_filter($array1, array($this'naz')));
    }

    protected function 
baz($var)
    {
        return(
$var 1);
    }
}

$bar = new Bar();
$bar->foo();
?>

[#23] John Erck: erck0006 at junkyo dot gmail dot com [2012-04-04 20:09:41]

<?php
// ARRAY FILTER RECURSIVE USING CLASS, STATIC METHOD, AND ANONYMOUS CALLBACK FUNCTION
// NOTE THAT THE CALLBACK HAS ACCESS TO BOTH THE KEY AND VALUE

// THE CLASS (FOR YOU TO COPY)
class ArrayUtil
{
public static function FilterRecursive(Array $source, $fn)
{
$result = array();
foreach ($source as $key => $value)
{
if (is_array($value))
{
$result[$key] = self::FilterRecursive($value, $fn);
continue;
}
if ($fn($key, $value))
{
$result[$key] = $value; // KEEP
continue;
}
}
return $result;
}
}

// EXAMPLE ANONYMOUS CALLBACK FUNCTION
$fn = function ($key, $value)
{
if (strpos($key, 'drop') !== FALSE)
{
return FALSE; // DROP
}
return TRUE; // KEEP
};

// EXAMPLE PRE FILTER TEST DATA
$preFilter = array(
'a' => 'one',
'b' => array(
'example_drop' => 'filter me out',
'example_keep' => 'keep me',
),
'c' => 'three',
);

// EXAMPLE USAGE CODE
echo '// print_r($preFilter);' . "\n";
print_r($preFilter);
$postFilter = ArrayUtil::FilterRecursive($preFilter, $fn);
echo "\n";
echo '// print_r($postFilter);' . "\n";
print_r($postFilter);

[#24] spam dot 2011 at rebell dot at [2011-11-21 02:28:29]

If you have not noticed already - array_filter() can be used to remove empty elements, since an empty string considered "false", if you not specify a callback

Keep in mind, that this will remove also some other values - so if you want a quick "remove empty elements from array" this function will be fine, as long as you dont have anything to keep, which casts to "false"

[#25] lisachenko dot it at HUMAN dot gmail dot com [2011-07-22 00:54:50]

You can access the current key of array by passing a reference to array into callback function and call key() and next() method in the callback function:
<?php
$data 
= array('first' => 1'second' => 2'third' => 3);
$data array_filter($data, function ($item) use (&$data) {
    echo 
"Filtering key "key($data), '<br>'PHP_EOL;
    
next($data);
    return 
false;
});
?>


However be careful with array internal pointer or use reset() method before calling array_filter().

[#26] breich at reich-consulting dot net [2010-12-15 11:19:05]

I built the following array_remove_keys() function to
remove one or more keys from an array.

<?php
 
function array_remove_keys($array$keys = array()) {
 
    
// If array is empty or not an array at all, don't bother
    // doing anything else.
    
if(empty($array) || (! is_array($array))) {
        return 
$array;
    }
 
    
// If $keys is a comma-separated list, convert to an array.
    
if(is_string($keys)) {
        
$keys explode(','$keys);
    }
 
    
// At this point if $keys is not an array, we can't do anything with it.
    
if(! is_array($keys)) {
        return 
$array;
    }
 
    
// array_diff_key() expected an associative array.
    
$assocKeys = array();
    foreach(
$keys as $key) {
        
$assocKeys[$key] = true;
    }
 
    return 
array_diff_key($array$assocKeys);
}
 
// Example:
$data = array(
    
'name' => 'Brian',
    
'address1' => '98 Market St.',
    
'address2' => 'N/A'
);
 
// Output before array_remove_keys()
var_dump($data);
 
// Remove address2 key.
$data array_remove_keys($data'address2');
 
// Output after array_remove_keys()
var_dump($data);
 

?>

[#27] rolf at example dot com [2010-11-08 11:06:16]

Here is how you could easily delete a specific value from an array with array_filter:

<?php
$array 
= array (13356);
$my_value 3;
$filtered_array array_filter($array, function ($element) use ($my_value) { return ($element != $my_value); } );
print_r($filtered_array);
?>


output:

Array
(
    [0] => 1
    [3] => 5
    [4] => 6
)

[#28] Peter Robinett [2010-08-12 08:09:07]

Because array_filter() preserves keys, you should consider the resulting array to be an associative array even if the original array had integer keys for there may be holes in your sequence of keys. This means that, for example, json_encode() will convert your result array into an object instead of an array. Call array_values() on the result array to guarantee json_encode() gives you an array.

[#29] acid24 at gmail dot com [2010-07-26 05:58:31]

A function that allows filtering an array by keys:

<?php
function array_filter_key$input$callback ) {
    if ( !
is_array$input ) ) {
        
trigger_error'array_filter_key() expects parameter 1 to be array, ' gettype$input ) . ' given'E_USER_WARNING );
        return 
null;
    }
    
    if ( empty( 
$input ) ) {
        return 
$input;
    }
    
    
$filteredKeys array_filterarray_keys$input ), $callback );
    if ( empty( 
$filteredKeys ) ) {
        return array();
    }
    
    
$input array_intersect_keyarray_flip$filteredKeys ), $input );
    
    return 
$input;
}

?>


Example:

<?php
$input 
array_fliprange'a''z' ) );

$consonants array_filter_key$arr, function( $elem ) {
    
$vowels "aeiou";
    return 
strpos$vowelsstrtolower$elem ) ) === false;
} );
?>


Outputs:

array(21) {
  ["b"]=>
  int(1)
  ["c"]=>
  int(2)
  ["d"]=>
  int(3)
  ["f"]=>
  int(5)
  ["g"]=>
  int(6)
  ["h"]=>
  int(7)
  ["j"]=>
  int(9)
  ["k"]=>
  int(10)
  ["l"]=>
  int(11)
  ["m"]=>
  int(12)
  ["n"]=>
  int(13)
  ["p"]=>
  int(15)
  ["q"]=>
  int(16)
  ["r"]=>
  int(17)
  ["s"]=>
  int(18)
  ["t"]=>
  int(19)
  ["v"]=>
  int(21)
  ["w"]=>
  int(22)
  ["x"]=>
  int(23)
  ["y"]=>
  int(24)
  ["z"]=>
  int(25)
}

[#30] Ant P. [2010-03-13 08:58:42]

If you're using filter_input_array, the values will be null on failure and anything else on success. Because array_filter by default removes false, 0 and "" you need to do extra work like this:
<?php
$input_array 
filter_input_array(INPUT_GET, array(
  
'var1' => FILTER_VALIDATE_BOOLEAN,
  
'var2' => FILTER_VALIDATE_INT
));

array_filter($input_array, function($a) { return !is_null($a) });
?>

[#31] webdesign at blackbyrd dot biz [2009-10-08 13:00:24]

Here's a function that will filter a multi-demensional array. This filter will return only those items that match the $value given

<?php
    

    
function filter_by_value ($array$index$value){ 
        if(
is_array($array) && count($array)>0)  
        { 
            foreach(
array_keys($array) as $key){
                
$temp[$key] = $array[$key][$index];
                 
                if (
$temp[$key] == $value){
                    
$newarray[$key] = $array[$key];
                }
            }
          }
      return 
$newarray
    } 
?>


Example:

<?php
$results 
= array(
   
=> array('key1' => '1''key2' => 2'key3' => 3),
   
=> array('key1' => '12''key2' => 22'key3' => 32
);

$nResults filter_by_value($results'key2''2');
?>


Output :

array(
    0 => array('key1' => '1', 'key2' => 2, 'key3' => 3)
);

[#32] mewsterus at yahoo dot com [2009-09-14 10:13:30]

Here's an easy way to get a combination of keys and values, such that if you don't specify a key you will get the value, and if you do specify a key you will get the key:

<?php
$array 
= array('One' => 'First''Second''Third''Four' => 'Fourth''Fifth');

var_dump(array_keys($array));

$names array_filter(array_keys($array), 'is_string') + array_values($array);
ksort($array);

var_dump($names);
?>


Outputs:

array(5) {
  [0]=>string(3) "One"
  [1]=>int(0)
  [2]=>int(1)
  [3]=>string(4) "Four"
  [4]=>int(2)
}
array(5) {
  [0]=>string(3) "One"
  [1]=>string(6) "Second"
  [2]=>string(5) "Third"
  [3]=>string(4) "Four"
  [4]=>string(5) "Fifth"
}

Without using ksort, the keys appear before the fallback values, instead of inline and appearing like they replace them, however the keys are intact (which is why ksort works) so it's only execution order.

[#33] mchargue at usc dot edu [2009-08-07 14:34:13]

Wanting to pass an additional to parameter to the callback function?  This worked for me, there's probably another way to accomplish this task but just so you see how it can be done.  (I actually used this technique to strip old dates out of an array) :

<?php
//define in global scope so functions can access
$var_to_pass null;

function 
myfilter($input_var_outer,$param) {

    global 
$var_to_pass;
    
$var_to_pass $param;

    function 
mycallback($input_var_inner) {
      global 
$var_to_pass;
      return (
$input_var_inner>$var_to_pass) ? true false;
    }

    
$return_arr array_filter($input_var_outer,'mycallback');
    
//re-key if you want
    
$return_arr array_merge(array(),$return_arr);
    return 
$return_arr;

}

$min 5;
$a = array(1,3,5,7,9);

//remove elements from array that are not greater than $min
$a myfilter($a,$min);

echo 
"<pre>";
print_r($a);
echo 
"</pre>";
?>


--

Output:
Array
(
    [0] => 7
    [1] => 9
)

[#34] chrisstocktonaz at gmail dot com [2009-04-30 09:34:06]

I use the following to see if a array consist of scalar values or null, but of course you could mix it up using any of the is_ functions.

<?php
if(count($data) !== count(array_filter($data'is_scalar') + array_filter($data'is_null'))) {
  throw new 
Exception('Array did not consist of scalar and null values');
}
?>

[#35] niehztog [2008-12-30 01:27:57]

In case you are interested (like me) in filtering out elements with certain key-names, array_filter won't help you. Instead you can use the following:

<?php
$arr 
= array( 'element1' => 1'element2' => 2'element3' => 3'element4' => );
$filterOutKeys = array( 'element1''element4' );

$filteredArr array_diff_key$arrarray_flip$filterOutKeys ) )
?>


Result will be something like this:
['element2'] => 2
['element3'] => 3

[#36] romain dot lamarche at gmail dot com [2008-12-11 06:39:13]

This function filters an array and remove all null values recursively.

<?php
  
function array_filter_recursive($input)
  {
    foreach (
$input as &$value)
    {
      if (
is_array($value))
      {
        
$value array_filter_recursive($value);
      }
    }
    
    return 
array_filter($input);
  }
?>


Or with callback parameter (not tested) :

<?php
  
function array_filter_recursive($input$callback null)
  {
    foreach (
$input as &$value)
    {
      if (
is_array($value))
      {
        
$value array_filter_recursive($value$callback);
      }
    }
    
    return 
array_filter($input$callback);
  }
?>

[#37] darren at dazwin dot com [2008-10-08 11:44:06]

Regarding comment about trimming empty strings, the code posted will get into an infinite loop if the array is reduced to zero elements. The following might be better:

<?php
function array_trim($array) {
    while (!empty(
$array) and strlen(reset($array)) === 0) {
        
array_shift($array);
    }
    while (!empty(
$array) and strlen(end($array)) === 0) {
        
array_pop($array);
    }
    return 
$array;
}
?>

[#38] sami [2008-10-03 23:11:45]

Yes, it may remove NULLS, but it also removes anything that factors to a FALSE as well; like FALSE and ZERO. :/

[#39] quecoder at gmail [2008-08-27 03:00:48]

// my implementation for array_filter  

function my_array_filter($array,$function,$preserve=true)
{
$return = array();
foreach ($array as $k=>$v)
{
if($function($v)==true) $return[$k]=$v;
}
if($preserve) return $return;
else return array_values($return);
}

function odd($value)
{
return ($value & 1);
}

$oddonly = array (1,2,3,4,5,6,7,8,9);
print_r(my_array_filter($oddonly,'odd',1));

//output 
//Array ( [0] => 1 [2] => 3 [4] => 5 [6] => 7 [8] => 9 ) 

//Khaled Mohammed

[#40] WASD [2008-07-29 04:53:48]

You can easily delete all NULL elements from array with following statement:

<?php
$arr 
array_filter($arr);
?>

[#41] Martin [2007-09-04 10:56:47]

This function trims empty strings from the beginning and end of an array.
It's useful when outputing plaintext files on a page and you want to skip empty lines at the beginning and end, but not within the text.

<?php
function array_trim($array) {
    while (
strlen(reset($array)) === 0) {
        
array_shift($array);
    }
    while (
strlen(end($array)) === 0) {
        
array_pop($array);
    }
    return 
$array;
}
?>


You might want to trim each element too.

[#42] Hayley Watson [2007-08-29 15:49:21]

Just a simplification of my function from last month.

<?php
function partition($input$callback=null)
{
    if(
is_null($callback))
        
$true array_filter($input);
    else
        
$true array_filter($input$callback);

    
$false array_diff_key($input$true);
}
?>

[#43] leon at darkk dot net dot ru [2007-05-22 12:15:17]

Here is a way to get customizable filter

<?php
function blablabla() {
    ....
    
$new getNewUidls();
    class 
UidlFilter {
        function 
UidlFilter($uidls) { $this->uidls $uidls; }
        function 
filter($metamsg) { return in_array($metamsg['uidl'], $this->uidls); }
    }
    
$msglist array_filter($msglist, array(new UidlFilter($new), 'filter');
    ....
}
?>

[#44] Fladnag - bahatest at ifrance dot com [2006-10-22 09:19:04]

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

[#45] ydotzhangatwriwindberdotorg [2006-01-17 13:57:25]

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. 

<?php
/////////////////////////////////////////////////////////////////
//    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);
}
?>

[#46] xert [2005-04-26 05:14:18]

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.

[#47] marc dot vanwoerkom at fernuni-hagen dot de [2004-07-05 08:09:16]

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.

[#48] Maxwel Leite [2004-05-11 08:17:27]

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

[#49] Jeremy [2003-12-29 13:31:35]

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:

<?php

$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**
        )
)

[#50] redshift at pandora dot be [2003-06-28 12:01:33]

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 :-)

[#51] skd2 at ece dot msstate dot edu [2003-05-14 15:24:58]

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.

[#52] ajohnson at speakeasy dot org [2002-09-27 12:42:51]

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)==&& $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)==&& $removeblanksflag)
        )
            
$thisarray[] = $value;
    return 
$thisarray;
}

$array1 = array ('the OtHeR thang','this''that''OtHer',''9101'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);
 
?>

[#53] ajohnson at speakeasy dot org [2002-08-17 13: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',''9101'fifty''other','','');

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

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

echo 
"filtered:\n";
print_r($array2);
?>

上一篇: 下一篇: