引数付きの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同様の方法でisLowerisGreaterisEqualなどだけで考えた-とデモを ...


良い回避策。保守可能なコードのために、より読みやすいメソッド呼び出しもサポートするようにクラスを変更すると役立つ場合があります。$ matches = $ myobj-> ArraySelect(Array( 'from' => $ arr、 'where' => $ foo、 'lessthan' => 12))
dreftymac

私はphp savyではないので、これは明らかな質問かもしれませんが、配列をarray_filterに渡してそれを機能させるにはどうすればよいですか?ドキュメントは、誰かのコメントを除いて、これについて決して話しません。
Nicola Pedretti 2017

1
@NicolaPedretti私はあなたが秒の引数について話していると思いますarray_filterか?それは単にcallableです。上記の場合にマッチングが「3型:Objectメソッド呼び出し」array(<instance>, <method-name>)、参照 PHP:コールバック/呼び出し可能-マニュアル
jensgram 2017

面白い。本当にハッキーな感じがします。メソッドを直接渡す方が直感的です。
Nicola Pedretti 2017

@nicolapedretti何年もPHPに触れていません。今ではそのほとんどは私にハッキーだと感じています:)
jensgram '18

260

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単語を使用してラムダに追加のパラメーターを提供できることを知りませんでした。貴重なヒントをありがとう!:)
フリオマリアメカハンセン

15
これは私の意見では最良の解決策です。それはシンプルで要領を得ています。PHPが無名関数がjavascriptのように親スコープで宣言された変数を使用することを許可しないのは残念です。
NadiaFaya 2013

4
便利でエレガント、短い、+ 1
Grokking

7
「どのように引数をarray_filterに追加できるか」という質問に答えるのはこれだけなので、これは受け入れられる解決策であると思います。他の答えは、クロージャまたはクラスを使用して、同じ結果への代替ルートを提供することです。
tao 2015年

ありがとう、相棒。パーフェクト
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
解決策をありがとう、それはきちんとしていますが、サーバーにphp 5.2があるので、私はjensgramの:)を使用することにバインドされています:)
ピスタッキオ

PHP <5.3では、使用できますcreate_function()
まともなダブラー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.