আর্গুমেন্ট সহ পিএইচপি অ্যারে_ ফিল্টার


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

আমি কীভাবে লোয়ার_থান_10 এ যুক্তি যুক্ত করতে পারি যাতে এটি চেক করার জন্য নম্বরটি গ্রহণ করে? যেমন, আমার যদি এটি থাকে:

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

এটি অ্যারে_ফিল্টার থেকে 10 থেকে $ নাম্বার বা যে কোনও নম্বর দিয়ে কীভাবে কল করবেন?

উত্তর:


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-> অ্যারেসিলিট (অ্যারে ('=' $ আরআর থেকে, 'যেখানে' => $ foo, 'লেস্টান' => 12))
ড্রেফটিম্যাক

আমি কোনও পিএইচপি স্যাভি নই, সুতরাং সম্ভবত এটি একটি সুস্পষ্ট প্রশ্ন, তবে আপনি কীভাবে অ্যারে_ফিল্টারটিতে অ্যারে পাস করতে পারেন এবং এখনও এটি কাজ করতে পারেন? কারও মন্তব্য ব্যতীত ডকুমেন্টেশন কখনও এ বিষয়ে কথা বলে না।
নিকোলা পেদ্রেটি

1
@ নিকোলাপ্রেডিটি আমি ধরে নিয়েছি আপনি কি কয়েক সেকেন্ডের যুক্তির কথা বলছেন array_filter? এটি কেবল একটি callable; উপরের ক্ষেত্রে "টাইপ 3: অবজেক্ট মেথড কল": array(<instance>, <method-name>)সিএফ মিলছে matching পিএইচপি: কলব্যাকস / কলযোগ্য - ম্যানুয়াল
জেনসগ্রাম

মজাদার. এটা আমার কাছে সত্যই হ্যাক লাগছে। সরাসরি পদ্ধতিটি পাস করা আরও স্বজ্ঞাত বলে মনে হচ্ছে।
নিকোলা পেদ্রাটি

@nicolapedretti আমি বেশ কয়েক বছর ধরে পিএইচপি স্পর্শ করিনি। এতক্ষণে এটি বেশিরভাগই আমার কাছে হ্যাকি অনুভব করে :)
জেনসগ্রাম

260

যদি আপনি পিএইচপি 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
এটি আমার মতে সেরা সমাধান। এটা সহজ এবং বিন্দু। এটি লজ্জাজনক যে পিএইচপি জাভাস্ক্রিপ্টের মতো অজানা ফাংশনগুলিকে প্যারেন্ট স্কোপ হিসাবে ঘোষিত ভেরিয়েবলগুলি ব্যবহার করতে দেয় না।
নাদিয়াফায়া

4
দরকারী, মার্জিত, সংক্ষিপ্ত, +1
গ্রোকিং

7
আমি বিশ্বাস করি এটি গ্রহণযোগ্য সমাধান হওয়া উচিত, কারণ এটিই কেবলমাত্র প্রশ্নের উত্তর দেয়: "অ্যারে_ফিল্টারটিতে কীভাবে যুক্তি যুক্ত করা যায়" । অন্যান্য উত্তরগুলি ক্লোজার বা ক্লাস ব্যবহার করে একই ফলাফলের বিকল্প রুট সরবরাহ করছে।
তাও

ধন্যবাদ দোস্ত. পারফেক্ট
অরুনজিথ আরএস

36

পিএইচপি 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
সমাধানটির জন্য ধন্যবাদ, এটি ঝরঝরে, তবে সার্ভারে আমার পিএইচপি 5.2 রয়েছে, তাই আমি জেনসগ্রামের ব্যবহার করতে বাধ্য আছি :)
পিস্তাকি

পিএইচপি <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')) );
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.