কীভাবে পিএইচপি-তে একটি বহুমাত্রিক অ্যারে কী => মান অনুসারে অনুসন্ধান করবেন


147

কী কী মান জোড় একটি বহুমাত্রিক অ্যারে পাওয়া গিয়েছিল সেখানে সমস্ত সাবহারে পাওয়ার কোনও দ্রুত উপায় আছে? অ্যারে কত গভীর হবে তা আমি বলতে পারি না।

সাধারণ উদাহরণ অ্যারে:

$arr = array(0 => array(id=>1,name=>"cat 1"),
             1 => array(id=>2,name=>"cat 2"),
             2 => array(id=>3,name=>"cat 1")
);

আমি যখন কী = নাম এবং মান = "বিড়াল 1" অনুসন্ধান করি তখন ফাংশনটি ফিরে আসবে:

array(0 => array(id=>1,name=>"cat 1"),
      1 => array(id=>3,name=>"cat 1")
);

আমার ধারণা ফাংশনটি গভীর স্তরে নামার জন্য পুনরাবৃত্ত হতে হবে।

উত্তর:


217

কোড:

function search($array, $key, $value)
{
    $results = array();

    if (is_array($array)) {
        if (isset($array[$key]) && $array[$key] == $value) {
            $results[] = $array;
        }

        foreach ($array as $subarray) {
            $results = array_merge($results, search($subarray, $key, $value));
        }
    }

    return $results;
}

$arr = array(0 => array(id=>1,name=>"cat 1"),
             1 => array(id=>2,name=>"cat 2"),
             2 => array(id=>3,name=>"cat 1"));

print_r(search($arr, 'name', 'cat 1'));

আউটপুট:

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => cat 1
        )

    [1] => Array
        (
            [id] => 3
            [name] => cat 1
        )

)

দক্ষতা যদি গুরুত্বপূর্ণ হয় তবে আপনি এটি লিখতে পারতেন যাতে সমস্ত পুনরাবৃত্ত কলগুলি তাদের ফলাফলগুলি $resultsএকসাথে অ্যারে মার্জ করার পরিবর্তে একই অস্থায়ী অ্যারে সংরক্ষণ করে:

function search($array, $key, $value)
{
    $results = array();
    search_r($array, $key, $value, $results);
    return $results;
}

function search_r($array, $key, $value, &$results)
{
    if (!is_array($array)) {
        return;
    }

    if (isset($array[$key]) && $array[$key] == $value) {
        $results[] = $array;
    }

    foreach ($array as $subarray) {
        search_r($subarray, $key, $value, $results);
    }
}

মূল কীটি search_rএটির চেয়ে চতুর্থ প্যারামিটারটি রেফারেন্স দ্বারা গ্রহণ করে; অ্যাম্পারস্যান্ডটি &গুরুত্বপূর্ণ।

অবগতির জন্য: আপনি পিএইচপি এর একটি পুরোনো সংস্করণ থাকে, তাহলে আপনি পাসের-বাই-রেফারেন্স অংশ নির্দিষ্ট করতে হবে কল করার search_rবদলে তার ঘোষণায়। যে, শেষ লাইন হয়ে যায় search_r($subarray, $key, $value, &$results)


2
@ জোহনকুগেলম্যান অ্যানারে $keyথাকা না থাকলে "দক্ষ" উত্তর ত্রুটিটি খুঁজে পাবে ? এটা কি আরও ভাল হবে if (array_key_exists($key, $array) && $array[$key] == $value) {?
চেজ

1
@ জনকুগেলম্যান এই ফাংশনটি দুর্দান্ত কাজ করে তবে কিছুটা সময় আমার কাছে $valueযা আমার হয় nullএবং ফাংশনটি কাজ করে না ... array empty... অ্যারে থাকলেও কীভাবে $value= null? পছন্দ search($array, 'id', null)?
জাগলু

71

পরিবর্তে এসপিএল সংস্করণ সম্পর্কে কীভাবে ? এটি আপনাকে কিছু টাইপ করে সংরক্ষণ করবে:

// I changed your input example to make it harder and
// to show it works at lower depths:

$arr = array(0 => array('id'=>1,'name'=>"cat 1"),
             1 => array(array('id'=>3,'name'=>"cat 1")),
             2 => array('id'=>2,'name'=>"cat 2")
);

//here's the code:

    $arrIt = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));

 foreach ($arrIt as $sub) {
    $subArray = $arrIt->getSubIterator();
    if ($subArray['name'] === 'cat 1') {
        $outputArray[] = iterator_to_array($subArray);
    }
}

কী দুর্দান্ত তা হ'ল মূলত একই কোডটি আপনার জন্য একটি ডিরেক্টরি অনুসারে পুনরাবৃত্তির ডিরেক্টরিতে পুনরাবৃত্তির ডিরেক্টরি ব্যবহার করে পুনরাবৃত্তির ডিরেক্টরি ব্যবহার করবে ite এসপিএল হ'ল রক্সর।

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


এটি একটি কবজির মতো কাজ করে এবং আমি আবার একই ধরণের সমস্যার জন্য এটি ব্যবহার করার পরিকল্পনা করি: ডি একমাত্র অদ্ভুত অংশটি অগ্রণীতে রয়েছে এবং getSubIterator ফাংশনটি instead সাব ভেরিয়েবলের পরিবর্তে RecursiveIteratorIterator এ ব্যবহার করছে। আমি ভেবেছিলাম প্রথমে এটি টাইপো ছিল তবে এটি সঠিক উপায়ে! ধন্যবাদ জারেড
bchhun

2
দুর্দান্ত সমাধান। খুব দ্রুত!
টেলরঅটওয়েল

সমাধানের জন্য আপনাকে ধন্যবাদ। আমরা কোথায় "আইডি" পাই? $ আউটপুটআরে থেকে?
ট্রান্টে

ধন্যবাদ, খুব সোজা এগিয়ে সমাধান, কিন্তু কর্মক্ষমতা সম্পর্কে জানেন না ??
মহেশ.ডে .14

আসল উপাদানটি কীভাবে মূল অ্যারে থেকে সেট করতে হবে (উপ-অ্যারে হতে পারে)?
Fr0zenFyr

49
<?php
$arr = array(0 => array("id"=>1,"name"=>"cat 1"),
             1 => array("id"=>2,"name"=>"cat 2"),
             2 => array("id"=>3,"name"=>"cat 1")
);
$arr = array_filter($arr, function($ar) {
   return ($ar['name'] == 'cat 1');
   //return ($ar['name'] == 'cat 1' AND $ar['id'] == '3');// you can add multiple conditions
});

echo "<pre>";
print_r($arr);

?>

তথ্যসূত্র: http://php.net/manual/en/function.array-filter.php


4
এটি একটি ভাল সমাধান যদি আপনি কেবল একটি মাত্র স্তর গভীর এমন একটি অ্যারে অনুসন্ধান করতে চান তবে এই বিশেষ প্রশ্নটি গভীরভাবে অ্যারেতে পুনরাবৃত্তভাবে অনুসন্ধান সম্পর্কে ছিল ("গভীরতর স্তরে নামার জন্য ফাংশনটি পুনরাবৃত্ত হতে হবে")।
অরর্ড

16

এই উত্তরগুলির জন্য যেহেতু একটি অপ্টিমাইজেশন টিপের প্রয়োজন হবে তার জন্য এই আপডেটটি পোস্ট করতে ফিরে এসেছিলেন, উপরে জোগুল কুগেলম্যানের দুর্দান্ত উত্তরটি বিশদ বিবরণ।

তার পোস্ট করা ফাংশনটি দুর্দান্ত কাজ করেছে তবে 12 000 সারির রেজসেটটি পরিচালনা করার জন্য আমাকে এই দৃশ্যটি অনুকূল করতে হয়েছিল। সমস্ত রেকর্ডটি যেতে ফাংশনটি চিরন্তন sec সেকেন্ড সময় নিচ্ছে, ওয়াহাআআআআআআআ।

অনুসন্ধানটি বন্ধ করতে এবং ম্যাচটি পাওয়া গেলে ফিরে আসার জন্য আমার কেবল ফাংশনটির প্রয়োজন ছিল। উদাহরণস্বরূপ, যদি গ্রাহক_আইডি সন্ধান করা হয়, আমরা জানি যে রেজাল্টটিতে আমাদের কেবল একটি রয়েছে এবং আমরা একবার গ্রাহক_আইটি বহুমাত্রিক অ্যারে খুঁজে পেয়েছি, আমরা ফিরে যেতে চাই।

এখানে প্রয়োজনের জন্য এই ফাংশনের গতি-অনুকূলিতকরণের (এবং অনেক সরলীকৃত) সংস্করণ এখানে। অন্যান্য সংস্করণ থেকে পৃথক, এটি কেবল অ্যারের কেবলমাত্র একটি গভীরতা পরিচালনা করতে পারে, পুনরাবৃত্তি করে না এবং একাধিক ফলাফল মার্জ করার পরেও চলে না।

// search array for specific key = value
public function searchSubArray(Array $array, $key, $value) {   
    foreach ($array as $subarray){  
        if (isset($subarray[$key]) && $subarray[$key] == $value)
          return $subarray;       
    } 
}

এটি 12,000 রেকর্ডকে 1.5 সেকেন্ডের সাথে মেলে টাস্কটি নামিয়ে আনে। এখনও খুব ব্যয়বহুল কিন্তু অনেক বেশি যুক্তিসঙ্গত।


এই এক দ্রুত Jhon চেয়ে / জ্যারেড এর উত্তর (0.0009999275207519) বনাম আছে (0.0020008087158203) .. আচ্ছা এই পরীক্ষা আমার ক্ষেত্রে ও পরিবেশ .. তোমার দর্শন লগ করা এই সঙ্গে স্টিকিং নির্দিষ্ট, ধন্যবাদ stefgosselin হয়
Awena থেকে

14
if (isset($array[$key]) && $array[$key] == $value)

দ্রুত সংস্করণে একটি ছোটখাট ছদ্মবেশ।


2
কীটি সেট না করা হলে এটি সতর্কতা নিক্ষেপ করতে বাধা দেয়। এতটা নাবালিকা না! -> +1 'হয়েছে।
স্টিফগোসেলিন

2
সম্মত হন, বড় ত্রুটিগুলির জন্য পিএইচপি ত্রুটি লগের দ্বারা আসলে নজর দেওয়াতে সক্ষম হওয়া এবং সতর্কতার সাথে এটি দূষিত না করা আমার মতে যাওয়ার উপায়।
কোডারকেপ

এটি সম্পূর্ণ সমাধান নয় এবং এটি একটি "অন্য পোস্টের প্রতি সাড়া দেওয়ার চেষ্টা" এবং "একটি উত্তর নয়" এরও বেশি is
মিকম্যাকুসা

7

একাধিক মাত্রিক অ্যারেতে রৈখিক অনুসন্ধান অ্যালগরিদমগুলি (উপরেরটি লিনিয়ারগুলি) সম্পর্কে সাবধান থাকুন কারণ তাদের মধ্যে জটিলতা রয়েছে কারণ এর গভীরতা পুরো অ্যারেটিকে অতিক্রম করার জন্য প্রয়োজনীয় পুনরাবৃত্তির সংখ্যা বৃদ্ধি করে। উদাহরণ:

array(
    [0] => array ([0] => something, [1] => something_else))
    ...
    [100] => array ([0] => something100, [1] => something_else100))
)

আপনি যা সন্ধান করছেন তা সন্ধান করতে সর্বাধিক 200 পুনরাবৃত্তি গ্রহণ করতে হবে (যদি সূচ [100] [1] এ থাকত), উপযুক্ত অ্যালগরিদম সহ।

এই ক্ষেত্রে লিনিয়ার অ্যালগোরিদমগুলি ও (এন) এ সঞ্চালিত হয় (পুরো অ্যারেতে সামগ্রীর সংখ্যার ক্রম অর্ডার করে), এটি দরিদ্র, একটি মিলিয়ন এন্ট্রি (উদাহরণস্বরূপ 1000x100x10 অ্যারে) সূগুলি সন্ধানের জন্য গড়ে 500,000 পুনরাবৃত্তি গ্রহণ করবে। এছাড়াও আপনি যদি আপনার বহুমাত্রিক অ্যারের কাঠামো পরিবর্তন করার সিদ্ধান্ত নিয়েছেন তবে কি হবে? এবং পিএইচপি যদি আপনার গভীরতা 100 এর বেশি হয় তবে পুনরাবৃত্তির একটি অ্যালগরিদম বের করে আনতে পারে Computer কম্পিউটার বিজ্ঞান আরও ভাল করতে পারে:

যেখানে সম্ভব, সর্বদা একাধিক মাত্রিক অ্যারের পরিবর্তে অবজেক্টগুলি ব্যবহার করুন:

ArrayObject(
   MyObject(something, something_else))
   ...
   MyObject(something100, something_else100))
)

এবং তাদের বাছাই করতে এবং এটির জন্য একটি কাস্টম তুলক ইন্টারফেস এবং ফাংশন প্রয়োগ করুন:

interface Comparable {
   public function compareTo(Comparable $o);
}

class MyObject implements Comparable {
   public function compareTo(Comparable $o){
      ...
   }
}

function myComp(Comparable $a, Comparable $b){
    return $a->compareTo($b);
}

আপনি uasort()একটি কাস্টম তুলককে কাজে লাগাতে ব্যবহার করতে পারেন , যদি আপনি দু: সাহসিক কাজ অনুভব করেন তবে আপনার নিজের বস্তুর জন্য তাদের নিজস্ব সংগ্রহগুলি প্রয়োগ করা উচিত যা তাদের সাজান এবং পরিচালনা করতে পারে (আমি সর্বদা খুব কমপক্ষে একটি অনুসন্ধান ফাংশন অন্তর্ভুক্ত করতে অ্যারেঅবজেক্টকে প্রসারিত করি)।

$arrayObj->uasort("myComp");

একবার তাদের বাছাই করা হয়ে গেলে (uasort হল ও (এন লগ এন), যা এটি সালিশী ডেটা ওভার হিসাবে ভাল হয়), বাইনারি অনুসন্ধান ও (লগ এন) সময়ে ক্রিয়াকলাপ করতে পারে, অর্থাত্ একটি মিলিয়ন এন্ট্রিগুলিতে কেবল ~ 20 পুনরাবৃত্তি লাগে অনুসন্ধান করুন। যতদূর আমি সচেতন কাস্টম তুলনাকারী বাইনারি অনুসন্ধান পিএইচপি তে প্রয়োগ করা হয়নি ( array_search()প্রাকৃতিক ক্রম ব্যবহার করে যা বস্তুর রেফারেন্সগুলিতে তাদের সম্পত্তি হিসাবে কাজ করে না), আপনাকে নিজের মতো করে নিজের মতো করে প্রয়োগ করতে হবে।

এই পদ্ধতির আরও দক্ষ (আরও গভীরতা নেই) এবং আরও গুরুত্বপূর্ণভাবে সার্বজনীন (আপনি ইন্টারফেস ব্যবহার করে তুলনীয়তা চাপিয়ে নিচ্ছেন) যেহেতু বস্তুগুলি কীভাবে সাজানো হয় তা নির্ধারণ করে, সুতরাং আপনি কোডটিকে অসীমভাবে পুনর্ব্যবহার করতে পারেন। অনেক ভাল =)


এই উত্তরটি সঠিক হওয়া উচিত। যদিও ব্রুট ফোর্স অনুসন্ধানের পদ্ধতি এটি করবে, এটি সংস্থান নিবিড় অনেক কম।
ড্রয়

এটি লক্ষ করা উচিত যে আপনি যা পরামর্শ দিচ্ছেন তা কেবল তখনই বোধগম্য হয় যদি আপনি একই অ্যারেটিকে বহুবার অনুসন্ধান করেন। এটি (O (n লগ এন)) বাছাইয়ের সমস্যাটি পেরিয়ে যাওয়ার জন্য এটির চেয়ে অনেক বেশি সময় নেয় (ও (এন)) মূল্যের জন্য কেবল রৈখিক অনুসন্ধান করতে। তবে একবার এটি বাছাই করার পরে, অবশ্যই, তারপরে একটি বাইনারি অনুসন্ধান দ্রুত হবে।
অরর্ড

আমার আরও যোগ করা উচিত যে অ্যারেগুলির পরিবর্তে অবজেক্টগুলি ব্যবহার করা একটি দরকারী বিমূর্ততা হতে পারে তবে অ্যারে বাছাই করা থাকলে আপনি অ্যারেতে বাইনারি অনুসন্ধানও করতে পারেন। আপনাকে অ্যারে বাছাই করতে বা এটিতে বাইনারি অনুসন্ধান করার জন্য অবজেক্টগুলি ব্যবহার করার দরকার নেই।
অরর্ড

6

সমাধান এখানে:

<?php
$students['e1003']['birthplace'] = ("Mandaluyong <br>");
$students['ter1003']['birthplace'] = ("San Juan <br>");
$students['fgg1003']['birthplace'] = ("Quezon City <br>");
$students['bdf1003']['birthplace'] = ("Manila <br>");

$key = array_search('Delata Jona', array_column($students, 'name'));
echo $key;  

?>


3

http://snipplr.com/view/51108/nested-array-search-by-value-or-key/

<?php

//PHP 5.3

function searchNestedArray(array $array, $search, $mode = 'value') {

    foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $key => $value) {
        if ($search === ${${"mode"}})
            return true;
    }
    return false;
}

$data = array(
    array('abc', 'ddd'),
    'ccc',
    'bbb',
    array('aaa', array('yyy', 'mp' => 555))
);

var_dump(searchNestedArray($data, 555));

3
function in_multi_array($needle, $key, $haystack) 
{
    $in_multi_array = false;
    if (in_array($needle, $haystack))
    {
        $in_multi_array = true; 
    }else 
    {
       foreach( $haystack as $key1 => $val )
       {
           if(is_array($val)) 
           {
               if($this->in_multi_array($needle, $key, $val)) 
               {
                   $in_multi_array = true;
                   break;
               }
           }
        }
    }

    return $in_multi_array;
} 

আমার কেস আলাদা তবে আপনার উত্তর থেকে ইঙ্গিত পেয়েছে।
shyammakwana.me

2

আমার অনুরূপ কিছু দরকার ছিল, তবে মূল্য দিয়ে বহুমাত্রিক অ্যারেটি অনুসন্ধান করার জন্য ... আমি জনকে উদাহরণ দিয়েছিলাম এবং লিখেছিলাম

function _search_array_by_value($array, $value) {
        $results = array();
        if (is_array($array)) {
            $found = array_search($value,$array);
            if ($found) {
                $results[] = $found;
            }
            foreach ($array as $subarray)
                $results = array_merge($results, $this->_search_array_by_value($subarray, $value));
        }
        return $results;
    }

আমি আশা করি এটি কাউকে সাহায্য করবে :)


2

এটি জন কে পোস্ট করেছে এমন একটির কাছ থেকে এটি একটি সংশোধিত ফাংশন ... আমাকে অ্যারেতে নির্দিষ্ট কী এবং এর উপরে কিছুই ধরতে হবে না।

function search_array ( $array, $key, $value )
{
    $results = array();

    if ( is_array($array) )
    {
        if ( $array[$key] == $value )
        {
            $results[] = $array;
        } else {
            foreach ($array as $subarray) 
                $results = array_merge( $results, $this->search_array($subarray, $key, $value) );
        }
    }

    return $results;
}

$arr = array(0 => array(id=>1,name=>"cat 1"),
       1 => array(id=>2,name=>"cat 2"),
       2 => array(id=>3,name=>"cat 1"));

print_r(search_array($arr, 'name', 'cat 1'));

1

এবং অন্য সংস্করণ যা অ্যারে উপাদান থেকে মূল মানটি দেয় যেখানে মানটি পাওয়া যায় (গতির জন্য পুনরাবৃত্তি হয় না):

// if the array is 
$arr['apples'] = array('id' => 1);
$arr['oranges'] = array('id' => 2);

//then 
print_r(search_array($arr, 'id', 2);
// returns Array ( [oranges] => Array ( [id] => 2 ) ) 
// instead of Array ( [0] => Array ( [id] => 2 ) )

// search array for specific key = value
function search_array($array, $key, $value) {
  $return = array();   
  foreach ($array as $k=>$subarray){  
    if (isset($subarray[$key]) && $subarray[$key] == $value) {
      $return[$k] = $subarray;
      return $return;
    } 
  }
}

যারা এখানে পোস্ট করেছেন তাদের সবাইকে ধন্যবাদ।


1
function findKey($tab, $key){
    foreach($tab as $k => $value){ 
        if($k==$key) return $value; 
        if(is_array($value)){ 
            $find = findKey($value, $key);
            if($find) return $find;
        }
    }
    return null;
}

2
আপনি এই উত্তরটি প্রসারিত করতে পারেন? কোডের উত্তরগুলি আপনি আসলে কি করছেন তা বোঝায় না।
ধনী বেনার

শিক্ষিত করার অভিপ্রায় সহ আপনার প্রশ্নটি আপডেট করুন।
মিকম্যাকুসা

এটি কেবল কী অনুসন্ধান করার জন্য কার্যকর, এটি আমার পক্ষে কাজ করে।
জিওভানি গঞ্জালেজ

0

আপনি যদি কীগুলির অ্যারের সন্ধান করতে চান তবে এটি ভাল

function searchKeysInMultiDimensionalArray($array, $keys)
{
    $results = array();

    if (is_array($array)) {
        $resultArray = array_intersect_key($array, array_flip($keys));
        if (!empty($resultArray)) {
            $results[] = $resultArray;
        }

        foreach ($array as $subarray) {
            $results = array_merge($results, searchKeysInMultiDimensionalArray($subarray, $keys));
        }
    }

    return $results;
}

কীগুলি ওভাররাইট হবে না কারণ কীগুলির প্রতিটি সেট => মানগুলি ফলাফলের অ্যারেতে পৃথক অ্যারেতে থাকবে।
আপনি যদি সদৃশ কী না চান তবে এটি ব্যবহার করুন

function searchKeysInMultiDimensionalArray($array, $keys)
{
    $results = array();

    if (is_array($array)) {
        $resultArray = array_intersect_key($array, array_flip($keys));
        if (!empty($resultArray)) {
            foreach($resultArray as $key => $single) {

                $results[$key] = $single;
            }
        }

        foreach ($array as $subarray) {
            $results = array_merge($results, searchKeysInMultiDimensionalArray($subarray, $keys));
        }
    }

    return $results;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.