পিএইচপি: অ্যারে কী ফিল্টার করতে অ্যারে_ফিল্টার () কীভাবে ব্যবহার করবেন?


363

কলব্যাক ফাংশনটি কেবল array_filter()অ্যারের মানগুলিতে যায়, কীগুলি নয়।

যদি আমার থাকে:

$my_array = array("foo" => 1, "hello" => "world");

$allowed = array("foo", "bar");

অ্যারেতে নেই $my_arrayএমন সমস্ত কী মুছে ফেলার সেরা উপায় কী $allowed?

পছন্দসই আউটপুট:

$my_array = array("foo" => 1);

নেই একটি সমাধান কিন্তু অন্য পদ্ধতির যে সহায়ক হতে পারে হয় $b = ['foo' => $a['foo'], 'bar' => $a['bar']]পরিণাম ডেকে আনবে এই $b['bar']হতে null
অরিয়াদাম

উত্তর:


322

পিএইচপি 5.6 তৃতীয় প্যারামিটারটি প্রচলন array_filter(), flag, আপনি সেট করতে পারেন যে ARRAY_FILTER_USE_KEYমানের পরিবর্তে কী দ্বারা ফিল্টার করুন:

$my_array = ['foo' => 1, 'hello' => 'world'];
$allowed  = ['foo', 'bar'];
$filtered = array_filter(
    $my_array,
    function ($key) use ($allowed) {
        return in_array($key, $allowed);
    },
    ARRAY_FILTER_USE_KEY
);

স্পষ্টতই এটি এর মতো মার্জিত নয় array_intersect_key($my_array, array_flip($allowed)), তবে এটি কীটির বিরুদ্ধে একটি স্বেচ্ছাসেবী পরীক্ষা করার অতিরিক্ত নমনীয়তা সরবরাহ করে, উদাহরণস্বরূপ $allowed, সরল স্ট্রিংয়ের পরিবর্তে রেজেক্স প্যাটার্ন থাকতে পারে।

আপনি ARRAY_FILTER_USE_BOTHআপনার ফিল্টার ফাংশনে মান এবং কী উভয়ই দিতে পেরে ব্যবহার করতে পারেন। এখানে প্রথমটির উপর ভিত্তি করে একটি স্বীকৃত উদাহরণ রয়েছে, তবে নোট করুন যে আমি $allowedএই পদ্ধতিতে এনকোডিং ফিল্টারিংয়ের নিয়মগুলিকে সুপারিশ করব না :

$my_array = ['foo' => 1, 'bar' => 'baz', 'hello' => 'wld'];
$allowed  = ['foo' => true, 'bar' => true, 'hello' => 'world'];
$filtered = array_filter(
    $my_array,
    function ($val, $key) use ($allowed) { // N.b. $val, $key not $key, $val
        return isset($allowed[$key]) && (
            $allowed[$key] === true || $allowed[$key] === $val
        );
    },
    ARRAY_FILTER_USE_BOTH
); // ['foo' => 1, 'bar' => 'baz']


1
ধন্যবাদ, এটি এর চেয়ে আরও ভালarray_intersect
brzuchal

461

সহ array_intersect_keyএবং array_flip:

var_dump(array_intersect_key($my_array, array_flip($allowed)));

array(1) {
  ["foo"]=>
  int(1)
}

1
আমি যদি জানতে চাই যে এটি আমার সমাধানের চেয়ে বেশি দক্ষ তবে কি? এটি অবশ্যই আরও মার্জিত :)
GWW

13
এটি সাধারণ সমাধান নয় কারণ এটি আদেশ দেয় যে প্রতিটি মানই অনন্য। সম্পাদনা: দুঃখিত .. আমি সমাধানটি ভুলভাবে পড়েছি। অনুমোদিত কীগুলিতে উল্টানো ভাল সমাধান (+1)
ম্যাথু

@ জিডাব্লুডাব্লু: আমি জানি না এটি আরও দক্ষ, টিবিএইচ কিনা। @ কনফোর্স: আমি আপনার বক্তব্য বোঝার ব্যাপারে নিশ্চিত নই একটি অ্যারেতে দুটি অভিন্ন কী থাকতে পারে না, সুতরাং এটি কেবলমাত্র $ my_array- এ উপস্থিত কীগুলিকে অনুমতি দেবে will
ভিনসেন্ট সাভার্ড

1
অথবা কেবল ARRAY_FILTER_USE_KEY: P
জুলিয়েন পালার্ড

1
কেন ব্যবহার করবেন array_flip? $allowedকীগুলির সাহায্যে কেবল সংজ্ঞা দিন :allowed = array ( 'foo' => 1, 'bar' => 1 );
যুবল এ।

43

আমারও একই কাজ করা দরকার, তবে array_filterকীগুলিতে আরও জটিল ।

অনুরূপ পদ্ধতি ব্যবহার করে আমি এটি কীভাবে করেছি তা এখানে।

// Filter out array elements with keys shorter than 4 characters
$a = array(
  0      => "val 0", 
  "one"  => "val one", 
  "two"  => "val two", 
  "three"=> "val three", 
  "four" => "val four", 
  "five" => "val five", 
  "6"    => "val 6"
); 

$f = array_filter(array_keys($a), function ($k){ return strlen($k)>=4; }); 
$b = array_intersect_key($a, array_flip($f));
print_r($b);

এটি ফলাফল প্রকাশ করে:

Array
(
    [three] => val three
    [four] => val four
    [five] => val five
)

8

ক্লোজারটি ব্যবহার করে এখানে আরও নমনীয় সমাধান দেওয়া হয়েছে:

$my_array = array("foo" => 1, "hello" => "world");
$allowed = array("foo", "bar");
$result = array_flip(array_filter(array_flip($my_array), function ($key) use ($allowed)
{
    return in_array($key, $allowed);
}));
var_dump($result);

আউটপুট:

array(1) {
  'foo' =>
  int(1)
}

সুতরাং ফাংশন, আপনি অন্যান্য নির্দিষ্ট পরীক্ষা করতে পারেন।


1
আমি একে "আরও নমনীয়" বলব না; এটি গ্রহণযোগ্য সমাধানের চেয়ে অনেক কম সোজা মনে হয়।
maček

আমি রাজী. এটি আরও নমনীয় হবে কারণ শর্তটি আরও জটিল ছিল।
কয়েল

1
অন্যান্য ব্যবহারকারীর জন্য কেবল পাশ দিয়ে যাচ্ছেন: solution my_array এর সদৃশ মান বা মানগুলি পূর্ণসংখ্যা বা স্ট্রিং নয় এমন ক্ষেত্রে মোকাবেলা করে না। সুতরাং আমি এই সমাধানটি ব্যবহার করব না।
ব্যবহারকারী 23127

2
আমি সম্মত হলাম এটি আরও নমনীয় কারণ এটি আপনাকে ফিল্টার যুক্তিকে পরিবর্তন করতে দেয়। উদাহরণস্বরূপ আমি নিষিদ্ধ কীগুলির একটি অ্যারে ব্যবহার করেছি এবং কেবল ফিরে এসেছি! In_array ($ কী, allow অস্বীকৃত)।
nfplee

5

আপনি কীগুলিতে সংঘটিত স্ট্রিংয়ের সাহায্যে অ্যারে ফিল্টার করার জন্য যদি কোনও পদ্ধতির সন্ধান করছেন তবে আপনি ব্যবহার করতে পারেন:

$mArray=array('foo'=>'bar','foo2'=>'bar2','fooToo'=>'bar3','baz'=>'nope');
$mSearch='foo';
$allowed=array_filter(
    array_keys($mArray),
    function($key) use ($mSearch){
        return stristr($key,$mSearch);
    });
$mResult=array_intersect_key($mArray,array_flip($allowed));

ফলাফল print_r($mResult)হয়

Array ( [foo] => bar [foo2] => bar2 [fooToo] => bar3 )

এই উত্তরের একটি অভিযোজন যা নিয়মিত প্রকাশকে সমর্থন করে supports

function array_preg_filter_keys($arr, $regexp) {
  $keys = array_keys($arr);
  $match = array_filter($keys, function($k) use($regexp) {
    return preg_match($regexp, $k) === 1;
  });
  return array_intersect_key($arr, array_flip($match));
}

$mArray = array('foo'=>'yes', 'foo2'=>'yes', 'FooToo'=>'yes', 'baz'=>'nope');

print_r(array_preg_filter_keys($mArray, "/^foo/i"));

আউটপুট

Array
(
    [foo] => yes
    [foo2] => yes
    [FooToo] => yes
)

আপনার উত্তরের জন্য ধন্যবাদ. আমি আপনাকে জমা দেব যে stristrফাংশন "কাজ" মধ্যে ব্যবহার করে শেষ ব্যবহারকারীর জন্য কিছু অনুমান করা হয়। সম্ভবত ব্যবহারকারীকে একটি নিয়মিত অভিব্যক্তি হিসাবে পাস করার অনুমতি দেওয়া ভাল; এটি তাদের অ্যাঙ্কর, শব্দের গণ্ডি এবং কেস সংবেদনশীলতা ইত্যাদির মতো কিছু বিষয়ে আরও
স্বাচ্ছন্দ্য বোধ করবে

আমি আপনার উত্তরের এমন একটি অভিযোজন যুক্ত করেছি যা অন্যান্য লোককে সহায়তা করতে পারে
20

1
আপনি অবশ্যই সত্য বলেছেন, হ'ল রেগেক্সের সাথে স্বাচ্ছন্দ্যযুক্ত ব্যবহারকারীদের পক্ষে এটি আরও বহুমুখী পদ্ধতি। ধন্যবাদ।
নিকোলাস জিমার

5

কীভাবে অ্যারের বর্তমান কীটি ব্যবহার করবেন array_filter

মায়েকের সমস্যার জন্য আমি ভিনসেন্টের সমাধানটি যেভাবেই পছন্দ করি না কেন, এটি আসলে ব্যবহার করে না array_filter। আপনি যদি কোনও অনুসন্ধান ইঞ্জিন থেকে এখানে এসে থাকেন তবে আপনি যেখানে এই জাতীয় কোনও সন্ধান করতে পারেন ( পিএইচপি> = 5.3 ):

$array = ['apple' => 'red', 'pear' => 'green'];
reset($array); // Unimportant here, but make sure your array is reset

$apples = array_filter($array, function($color) use ($&array) {
  $key = key($array);
  next($array); // advance array pointer

  return key($array) === 'apple';
}

এটি কলব্যাকের রেফারেন্স হিসাবে আপনি যে অ্যারে ফিল্টার করছেন তা পাস করে। যেমন array_filterএটি সার্বজনীন অভ্যন্তরীণ পয়েন্টার বৃদ্ধি করে অ্যারের উপরে পুনরাবৃত্তি হয় না আপনাকে নিজের দ্বারা এটি এগিয়ে নিতে হবে।

এখানে গুরুত্বপূর্ণ এটি হ'ল আপনার অ্যারেটি পুনরায় সেট করা হয়েছে তা নিশ্চিত করা দরকার, অন্যথায় আপনি এটির ঠিক মাঝখানে শুরু করতে পারেন।

ইন পিএইচপি> = 5.4 আপনি কলব্যাক এমনকি খাটো করতে পারে:

$apples = array_filter($array, function($color) use ($&array) {
  return each($array)['key'] === 'apple';
}

3

আনসেট () ব্যবহার করে এখানে একটি কম নমনীয় বিকল্প রয়েছে :

$array = array(
    1 => 'one',
    2 => 'two',
    3 => 'three'
);
$disallowed = array(1,3);
foreach($disallowed as $key){
    unset($array[$key]);
}

print_r($array)হওয়ার ফলাফল :

Array
(
    [2] => two
)

আপনি যদি ফিল্টারকৃত মানগুলি পরে ব্যবহারের জন্য তবে পরিপাটি করে রাখতে চান তবে এটি প্রযোজ্য নয় , যদি আপনি নিশ্চিত হন যে আপনি তা করেন না।


1
আনসেট না করার আগে আপনার কী $ কী $ অ্যারেতে উপস্থিত রয়েছে কিনা তা পরীক্ষা করা উচিত।
জারেক জাকুবউস্কি

3
@ জেরাক জাকুবউস্কি ব্যবহার করার সময় আপনাকে কোন অ্যারে কী উপস্থিত রয়েছে কিনা তা খতিয়ে দেখার দরকার নেই unset()। কীটি উপস্থিত না থাকলে কোনও সতর্কতা জারি করা হয় না।
ক্রিস্টোফার

3

পিএইচপি 5.6 থেকে শুরু করে আপনি এখানে ARRAY_FILTER_USE_KEYপতাকাটি ব্যবহার করতে পারেন array_filter:

$result = array_filter($my_array, function ($k) use ($allowed) {
    return in_array($k, $allowed);
}, ARRAY_FILTER_USE_KEY);


অন্যথায়, আপনি এই ফাংশনটি ব্যবহার করতে পারেন ( টেস্টডমি থেকে ):

function filter_array_keys(array $array, $callback)
{
    $matchedKeys = array_filter(array_keys($array), $callback);

    return array_intersect_key($array, array_flip($matchedKeys));
}

$result = filter_array_keys($my_array, function ($k) use ($allowed) {
    return in_array($k, $allowed);
});


এবং এখানে আমার একটি বাড়ানো সংস্করণ, যা একটি কলব্যাক বা সরাসরি কীগুলি গ্রহণ করে:

function filter_array_keys(array $array, $keys)
{
    if (is_callable($keys)) {
        $keys = array_filter(array_keys($array), $keys);
    }

    return array_intersect_key($array, array_flip($keys));
}

// using a callback, like array_filter:
$result = filter_array_keys($my_array, function ($k) use ($allowed) {
    return in_array($k, $allowed);
});

// or, if you already have the keys:
$result = filter_array_keys($my_array, $allowed));


সর্বশেষে তবে সর্বনিম্ন নয়, আপনি একটি সাধারণ ব্যবহার করতে পারেন foreach:

$result = [];
foreach ($my_array as $key => $value) {
    if (in_array($key, $allowed)) {
        $result[$key] = $value;
    }
}

1

সম্ভবত একবারের প্রয়োজন হলে ওভারকিল, তবে সংগ্রহগুলি ফিল্টার করতে আপনি ইয়লিনকো লাইব্রেরি * ব্যবহার করতে পারেন (এবং অন্য কোনও রূপান্তর সম্পাদন করতে পারেন )। এই গ্রন্থাগারটি সাবলীল সিনট্যাক্সযুক্ত বস্তুগুলিতে এসকিউএল-এর মতো প্রশ্নের উত্সাহ দেয়। এর whereফাংশনটি দুটি আর্গুমেন্টের সাথে একটি ক্যালব্যাক গ্রহণ করে: একটি মান এবং কী। উদাহরণ স্বরূপ:

$filtered = from($array)
    ->where(function ($v, $k) use ($allowed) {
        return in_array($k, $allowed);
    })
    ->toArray();

( whereফাংশনটি একটি পুনরুক্তি ফেরত দেয়, সুতরাং যদি আপনাকে কেবল foreachএকবার ফলস্বরূপ ক্রমের সাথে পুনরাবৃত্তি ->toArray()করতে হয় , সরিয়ে ফেলা যায়))

* আমার দ্বারা বিকাশিত


1

পিএইচপি থেকে অ্যারের ফিল্টার ফাংশন:

array_filter ( $array, $callback_function, $flag )

$ অ্যারে - এটি ইনপুট অ্যারে

$ কলব্যাক_ফান্শন - কলব্যাক ফাংশনটি ব্যবহার করার জন্য , যদি কলব্যাক ফাংশনটি সত্য করে দেয় তবে অ্যারে থেকে বর্তমান মান ফলাফলের অ্যারেতে ফিরে আসবে।

$ পতাকা - এটি alচ্ছিক প্যারামিটার , এটি কলব্যাক ফাংশনে কোন যুক্তি প্রেরণ করা হবে তা নির্ধারণ করবে। যদি এই পরামিতিটি খালি হয় তবে কলব্যাক ফাংশন আর্গুমেন্ট হিসাবে অ্যারের মানগুলি গ্রহণ করবে। আপনি যদি আর্গুমেন্ট হিসাবে অ্যারে কীটি প্রেরণ করতে চান তবে $ ফ্ল্যাটটি ARRAY_FILTER_USE_KEY হিসাবে ব্যবহার করুন । আপনি যদি কী এবং মান উভয়ই প্রেরণ করতে চান তবে আপনার should ফ্ল্যাটটি ARRAY_FILTER_USE_BOTH হিসাবে ব্যবহার করা উচিত ।

উদাহরণস্বরূপ: সাধারণ অ্যারে বিবেচনা করুন

$array = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);

আপনি যদি অ্যারে কী এর উপর ভিত্তি করে অ্যারে ফিল্টার করতে চান তবে আমাদের অ্যারে ফাংশন অ্যারে_ফিল্টারের তৃতীয় প্যারামিটার হিসাবে ARRAY_FILTER_USE_KEY ব্যবহার করা দরকার ।

$get_key_res = array_filter($array,"get_key",ARRAY_FILTER_USE_KEY );

আপনি যদি অ্যারে কী এবং অ্যারের মানের উপর ভিত্তি করে অ্যারে ফিল্টার করতে চান তবে আমাদের অ্যারে ফাংশন অ্যারে_ফিল্টারের তৃতীয় প্যারামিটার হিসাবে ARRAY_FILTER_USE_BOTH ব্যবহার করতে হবে ।

$get_both = array_filter($array,"get_both",ARRAY_FILTER_USE_BOTH );

নমুনা কলব্যাক ফাংশন:

 function get_key($key)
 {
    if($key == 'a')
    {
        return true;
    } else {
        return false;
    }
}
function get_both($val,$key)
{
    if($key == 'a' && $val == 1)
    {
        return true;
    }   else {
        return false;
    }
}

এটি আউটপুট হবে

Output of $get_key is :Array ( [a] => 1 ) 
Output of $get_both is :Array ( [a] => 1 ) 

0

এই ফাংশনটির সাহায্যে আপনি একটি বহুমাত্রিক অ্যারে ফিল্টার করতে পারেন

function filter_array_keys($array,$filter_keys=array()){

    $l=array(&$array);
    $c=1;
    //This first loop will loop until the count var is stable//
    for($r=0;$r<$c;$r++){
        //This loop will loop thru the child element list//
        $keys = array_keys($l[$r]);

        for($z=0;$z<count($l[$r]);$z++){
            $object = &$l[$r][$keys[$z]];

            if(is_array($object)){
                $i=0;
                $keys_on_array=array_keys($object);
                $object=array_filter($object,function($el) use(&$i,$keys_on_array,$filter_keys){
                    $key = $keys_on_array[$i];
                    $i++;

                    if(in_array($key,$filter_keys) || is_int($key))return false;                
                    return true;                        
                });
            }

            if(is_array($l[$r][$keys[$z]])){
                $l[] = &$l[$r][$keys[$z]];
                $c++;
            }//IF           
        }//FOR
    }//FOR  

    return $l[0];

}

0
// Filter out array elements with keys shorter than 4 characters 
// By using Anonymous function with  Closure...     

function comparison($min)
{
   return function($item) use ($min) { 
      return strlen($item) >= $min;   
   }; 
}

$input = array(
  0      => "val 0",
  "one"  => "val one",
  "two"  => "val two",
  "three"=> "val three",
  "four" => "val four",  
  "five" => "val five",    
  "6"    => "val 6"    
);

$output = array_filter(array_keys($input), comparison(4));    

print_r($output);

রান থেকে আউটপুট


0

নিষ্পাপ এবং কদর্য (তবে দ্রুত বলে মনে হয়) এর সমাধান?

এটি কেবল পিএইচপি 7.৩.১১-এ চেষ্টা করেছেন তবে একটি কুশল লুপ প্রায় এক তৃতীয়াংশ সময়ে কার্যকর হবে বলে মনে হয়। কয়েকশ কী সহ একটি অ্যারেতে অনুরূপ ফলাফল। মাইক্রো-অপ্টিমাইজেশান, সম্ভবত আরডাব্লুতে কার্যকর নয় তবে এটি অবাক করা এবং আকর্ষণীয় বলে মনে করেছে:

$time = microtime(true);
$i = 100000;
while($i) {
    $my_array = ['foo' => 1, 'hello' => 'world'];
    $allowed  = ['foo', 'bar'];
    $filtered = array_filter(
        $my_array,
        function ($key) use ($allowed) {
            return in_array($key, $allowed);
        },
        ARRAY_FILTER_USE_KEY
    );
    $i--;
}
print_r($filtered);
echo microtime(true) - $time . ' on array_filter';

// 0.40600109100342 on array_filter
$time2 = microtime(true);
$i2 = 100000;
while($i2) {
    $my_array2 = ['foo' => 1, 'hello' => 'world'];
    $allowed2  = ['foo', 'bar'];
    $filtered2 = [];
    foreach ($my_array2 as $k => $v) {
        if (in_array($k, $allowed2)) $filtered2[$k] = $v;
    }
    $i2--;
}
print_r($filtered2);
echo microtime(true) - $time2 . ' on ugly loop';
// 0.15677785873413 on ugly loop

-1
$elements_array = ['first', 'second'];

কিছু অ্যারে উপাদানগুলি সরিয়ে ফাংশন

function remove($arr, $data) {
    return array_filter($arr, function ($element) use ($data) {
        return $element != $data;
    });
}

কল এবং প্রিন্ট

print_r(remove($elements_array, 'second'));

ফলাফল Array ( [0] => first )


প্রশ্নটি অ্যারে কীগুলি ফিল্টারিংয়ের ক্ষেত্রে মানগুলি নয়।
পোলেটিউ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.