인수가있는 PHP array_filter


108

다음 코드가 있습니다.

function lower_than_10($i) {
    return ($i < 10);
}

다음과 같이 배열을 필터링하는 데 사용할 수 있습니다.

$arr = array(7, 8, 9, 10, 11, 12, 13);
$new_arr = array_filter($arr, 'lower_than_10');

검사 할 숫자를 허용하도록 lower_than_10에 인수를 추가하려면 어떻게해야합니까? 내가 이것을 가지고 있다면 :

function lower_than($i, $num) {
    return ($i < $num);
}

10을 $ num 또는 어떤 숫자로 전달하는 array_filter에서 호출하는 방법은 무엇입니까?

답변:


64

클로저를 사용하는 @Charles솔루션에 대한 대안으로 실제로 문서 페이지 의 주석 에서 예제 찾을 수 있습니다 . 아이디어는 원하는 상태 ( $num)와 콜백 메서드 ( $i인수로 사용)로 객체를 만드는 것입니다 .

class LowerThanFilter {
        private $num;

        function __construct($num) {
                $this->num = $num;
        }

        function isLower($i) {
                return $i < $this->num;
        }
}

사용법 ( 데모 ) :

$arr = array(7, 8, 9, 10, 11, 12, 13);
$matches = array_filter($arr, array(new LowerThanFilter(12), 'isLower'));
print_r($matches);

(!) 참고로, 당신은 지금 대체 할 수있는 LowerThanFilter보다 일반적인와 NumericComparisonFilter같은 방법으로 isLower, isGreater, isEqual등 그냥 생각 - 그리고 데모를 ...


좋은 해결 방법입니다. 코드 유지 관리를 위해 더 읽기 쉬운 메서드 호출을 지원하도록 클래스를 수정하는 것이 도움이 될 수 있습니다. $ matches = $ myobj-> ArraySelect (Array ( 'from'=> ​​$ arr, 'where'=> $ foo, 'lessthan'=> 12))
dreftymac

나는 PHP에 정통한 사람이 아니므로 이것은 분명한 질문 일 수 있지만 배열을 array_filter에 전달하고 여전히 작동하도록 만들 수 있습니까? 문서는 누군가의 의견을 제외하고는 이것에 대해 이야기하지 않습니다.
Nicola Pedretti

1
@NicolaPedretti 나는 당신이 초 인수에 대해 이야기하고 있다고 가정 array_filter합니까? 그것은 단순히 callable; 위의 경우 "유형 3 : 객체 메소드 호출"과 일치하는 경우 : array(<instance>, <method-name>), cf. PHP : 콜백 / Callables-Manual .
jensgram

흥미 롭군. 나에게 정말 끔찍한 느낌이 든다. 방법을 직접 전달하는 것이 더 직관적 인 것 같습니다.
Nicola Pedretti

@nicolapedretti 몇 년 동안 PHP를 다루지 않았습니다. 지금까지 그것의 대부분은 : 나에게 해키 느낌
jensgram

261

php 5.3 이상을 사용하는 경우 클로저 를 사용하여 코드를 단순화 할 수 있습니다.

$NUM = 5;
$items = array(1, 4, 5, 8, 0, 6);
$filteredItems = array_filter($items, function($elem) use($NUM){
    return $elem < $NUM;
});

12
use람다에 추가 매개 변수를 제공하기 위해 단어를 사용할 수 있다는 것을 몰랐습니다 . 귀중한 힌트 주셔서 감사합니다! :)
Julio María Meca Hansen 2013

15
이것은 제 생각에 최선의 해결책입니다. 간단하고 요점입니다. PHP가 자바 스크립트와 같이 부모 범위에서 선언 된 변수를 익명 함수가 사용하도록 허용하지 않는 것은 유감입니다.
NadiaFaya 2013 년

4
유용한, 우아한, 짧은, 한
Grokking

7
나는 이것이 "어떻게 array_filter에 인수를 추가 할 수 있는가" 라는 질문에 답하는 유일한 해결책이기 때문에 받아 들여진 해결책이어야한다고 생각합니다 . 다른 답변은 클로저 또는 클래스를 사용하여 동일한 결과에 대한 대체 경로를 제공합니다.
tao

고마워 친구. Perfect
Arunjith RS

36

PHP 5.3 이상에서는 클로저를 사용할 수 있습니다 .

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

1
솔루션에 대한 감사는 깔끔하지만, 내가 사용 jensgram의 : 결합하고있어 그래서, 서버에 PHP 5.2이
pistacchio

php <5.3에서는 create_function().
Decent Dabbler 2011 년

3
create_function()기본적 eval()으로 다른 이름을 사용하고 있으며 마찬가지로 악합니다. 사용하지 않는 것이 좋습니다. 허용 된 답변에 제공된 이상한 클래스 기반 해결 방법 create_function()은이 경우 사용 하는 것보다 더 나은 솔루션 입니다.
Charles

20

여러 매개 변수를 함수에 전달해야하는 경우 ","를 사용하여 use 문에 추가 할 수 있습니다.

$r = array_filter($anArray, function($anElement) use ($a, $b, $c){
    //function body where you may use $anElement, $a, $b and $c
});

14

jensgram 답변의 확장 에서 __invoke()magic 메서드 를 사용하여 더 많은 마법을 추가 할 수 있습니다 .

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

이것은 당신이 할 수 있습니다

$arr = array(7, 8, 9, 10, 11, 12, 13);
$matches = array_filter($arr, new LowerThanFilter(12));
print_r($matches);

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


}

이를 통해 다차원 배열의 항목을 필터링 할 수 있습니다.

$users = array();
$users[] = array('email' => 'user1@email.com','name' => 'Robert');
$users[] = array('email' => 'user2@email.com','name' => 'Carl');
$users[] = array('email' => 'user3@email.com','name' => 'Robert');

//Print all users called 'Robert'
print_r( array_filter($users, new ArraySearcher('name',ArraySearcher::OPERATOR_EQUALS,'Robert')) );
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.