keys - PHP array_filter con argumentos
in array php (6)
Tengo el siguiente código:
function lower_than_10($i) {
return ($i < 10);
}
que puedo usar para filtrar una matriz como esta:
$arr = array(7, 8, 9, 10, 11, 12, 13);
$new_arr = array_filter($arr, ''lower_than_10'');
¿Cómo puedo agregar argumentos a lower_than_10 para que también acepte el número para verificar? Me gusta, si tengo esto:
function lower_than($i, $num) {
return ($i < $num);
}
cómo llamarlo desde array_filter pasando 10 a $ num o cualquier número?
Como alternativa a la solución de @ Charles que utiliza cierres , puede encontrar un ejemplo en los comentarios en la página de documentación. La idea es crear un objeto con el estado deseado ( $num
) y el método de devolución de llamada (tomando $i
como argumento):
class LowerThanFilter {
private $num;
function __construct($num) {
$this->num = $num;
}
function isLower($i) {
return $i < $this->num;
}
}
Uso ( demo ):
$arr = array(7, 8, 9, 10, 11, 12, 13);
$matches = array_filter($arr, array(new LowerThanFilter(12), ''isLower''));
print_r($matches);
Como nota al margen, ahora puede reemplazar a LowerThanFilter
con un LowerThanFilter
más genérico con métodos como isLower
, isGreater
, isEqual
, etc. Solo un pensamiento, y una demo ...
En PHP 5.3 o superior, puede usar un closure :
function create_lower_than($number = 10) {
// The "use" here binds $number to the function at declare time.
// This means that whenever $number appears inside the anonymous
// function, it will have the value it had when the anonymous
// function was declared.
return function($test) use($number) { return $test < $number; };
}
// We created this with a ten by default. Let''s test.
$lt_10 = create_lower_than();
var_dump($lt_10(9)); // True
var_dump($lt_10(10)); // False
var_dump($lt_10(11)); // False
// Let''s try a specific value.
$lt_15 = create_lower_than(15);
var_dump($lt_15(13)); // True
var_dump($lt_15(14)); // True
var_dump($lt_15(15)); // False
var_dump($lt_15(16)); // False
// The creation of the less-than-15 hasn''t disrupted our less-than-10:
var_dump($lt_10(9)); // Still true
var_dump($lt_10(10)); // Still false
var_dump($lt_10(11)); // Still false
// We can simply pass the anonymous function anywhere that a
// ''callback'' PHP type is expected, such as in array_filter:
$arr = array(7, 8, 9, 10, 11, 12, 13);
$new_arr = array_filter($arr, $lt_10);
print_r($new_arr);
En extensión a la respuesta del jensgram puedes agregar algo más de magia usando el método mágico __invoke()
.
class LowerThanFilter {
private $num;
public function __construct($num) {
$this->num = $num;
}
public function isLower($i) {
return $i < $this->num;
}
function __invoke($i) {
return $this->isLower($i);
}
}
Esto te permitirá hacer
$arr = array(7, 8, 9, 10, 11, 12, 13);
$matches = array_filter($arr, new LowerThanFilter(12));
print_r($matches);
Si usa php 5.3 o superior, puede usar el closure para simplificar su código:
$NUM = 5;
$items = array(1, 4, 5, 8, 0, 6);
$filteredItems = array_filter($items, function($elem) use($NUM){
return $elem < $NUM;
});
si necesita pasar múltiples parámetros a la función, puede agregarlos a la declaración de uso usando ",":
$r = array_filter($anArray, function($anElement) use ($a, $b, $c){
//function body where you may use $anElement, $a, $b and $c
});
class ArraySearcher{
const OPERATOR_EQUALS = ''=='';
const OPERATOR_GREATERTHAN = ''>'';
const OPERATOR_LOWERTHAN = ''<'';
const OPERATOR_NOT = ''!='';
private $_field;
private $_operation;
private $_val;
public function __construct($field,$operation,$num) {
$this->_field = $field;
$this->_operation = $operation;
$this->_val = $num;
}
function __invoke($i) {
switch($this->_operation){
case ''=='':
return $i[$this->_field] == $this->_val;
break;
case ''>'':
return $i[$this->_field] > $this->_val;
break;
case ''<'':
return $i[$this->_field] < $this->_val;
break;
case ''!='':
return $i[$this->_field] != $this->_val;
break;
}
}
}
Esto le permite filtrar elementos en matrices multidimensionales:
$users = array();
$users[] = array(''email'' => ''[email protected]'',''name'' => ''Robert'');
$users[] = array(''email'' => ''[email protected]'',''name'' => ''Carl'');
$users[] = array(''email'' => ''[email protected]'',''name'' => ''Robert'');
//Print all users called ''Robert''
print_r( array_filter($users, new ArraySearcher(''name'',ArraySearcher::OPERATOR_EQUALS,''Robert'')) );