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

मैं तर्कों को low_than_10 में कैसे जोड़ सकता हूं ताकि यह भी जाँचने के लिए संख्या को स्वीकार करे? जैसे, अगर मेरे पास यह है:

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

इसे array_filter से 10 से $ num या जो भी संख्या है, कैसे कॉल करें?

जवाबों:


64

@ चार्ल्स के समाधान के उपयोग के विकल्प के रूप में , आप वास्तव में प्रलेखन पृष्ठ पर टिप्पणियों में एक उदाहरण पा सकते हैं । विचार यह है कि आप इच्छित राज्य ( $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);

एक sidenote के रूप में, अब आप बदल सकते हैं LowerThanFilterएक अधिक सामान्य के साथ NumericComparisonFilterकी तरह के तरीकों के साथ isLower, isGreater, isEqualआदि बस एक सोचा - और एक डेमो ...


अच्छा वर्कअराउंड। बनाए रखने योग्य कोड के लिए, यह अधिक पठनीय विधि कॉल का समर्थन करने के लिए कक्षा को संशोधित करने में मदद कर सकता है: $ मैच = $ myobj-> ArraySelect (Array ('से =' $ arrest ', जहां' = '$ foo,) 'लेसस्टान' => 12))
dreftymac

मैं php सेवी नहीं हूं, इसलिए हो सकता है कि यह एक स्पष्ट सवाल हो, लेकिन आप array_filter के एरे में कैसे पास हो सकते हैं और फिर भी यह काम कर सकता है? प्रलेखन कभी भी इस बारे में बात नहीं करता है, सिवाय किसी की टिप्पणी के।
निकोला पेडरेटी

1
@ NicolaPedretti मुझे लगता है कि आप सेकंड के तर्क के बारे में बात कर रहे हैं array_filter? यह बस एक है callable; उपरोक्त मामले में "टाइप 3: ऑब्जेक्ट मेथड कॉल" मिलान:, array(<instance>, <method-name>)cf. PHP: कॉलबैक / कॉलबल्स - मैनुअल
जेन्सग्राम

दिलचस्प। यह वास्तव में मेरे लिए हैकिंग महसूस करता है। विधि को सीधे पास करना अधिक सहज लगता है।
निकोला पेड्रेती

@nicolapedretti मैंने कई वर्षों तक PHP को नहीं छुआ है। अब तक यह सबसे ज्यादा मेरे लिए
हैकी

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 अनाम फ़ंक्शंस को जावास्क्रिप्ट दायरे की तरह मूल कार्यक्षेत्र में घोषित चर का उपयोग करने की अनुमति नहीं देता है।
नाडियाफै

4
उपयोगी, सुरुचिपूर्ण, लघु, +1
ग्रॉकिंग

7
मेरा मानना ​​है कि यह स्वीकृत समाधान होना चाहिए, क्योंकि यह एकमात्र ऐसा है जो प्रश्न का उत्तर देता है: "array_fitter में तर्क कैसे जोड़ सकते हैं" । अन्य उत्तर या तो क्लोजर या कक्षाओं का उपयोग करके, उसी परिणाम के लिए वैकल्पिक मार्ग प्रदान कर रहे हैं।
ताओ

धन्यवाद दोस्त। बिल्कुल सही
अरुणजीत आरएस

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 का उपयोग करने के लिए बाध्य हूं :)
pistacchio

Php <5.3 में आप उपयोग कर सकते हैं create_function()
डिसेंट डब्बल

3
create_function()मूल रूप eval()से एक और नाम के साथ है, और बस बुराई के रूप में है। इसके उपयोग को हतोत्साहित किया जाना चाहिए। स्वीकृत उत्तर में दिया गया निराला वर्ग आधारित वर्कअराउंड create_function()इस मामले में उपयोग करने से बेहतर समाधान है ।
चार्ल्स

20

यदि आपको फ़ंक्शन में पास होने के लिए कई मापदंडों की आवश्यकता होती है, तो आप उन्हें "," का उपयोग करते हुए स्टेटमेंट में जोड़ सकते हैं।

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

14

जेन्सग्राम उत्तर के विस्तार में आप __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);
    }
}

यह आपको करने की अनुमति देगा

$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')) );
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.