PHP बहुआयामी ऐरे खोज (विशिष्ट मूल्य द्वारा कुंजी खोजें)


114

मेरे पास यह बहुआयामी सरणी है। मुझे इसे खोजने और केवल उस कुंजी को वापस करने की आवश्यकता है जो "स्लग" के मूल्य से मेल खाती है। मुझे पता है कि बहुआयामी सरणियों की खोज के बारे में अन्य सूत्र हैं, लेकिन मैं वास्तव में अपनी स्थिति पर लागू करने के लिए पर्याप्त समझ नहीं पा रहा हूं। किसी भी मदद के लिए बहुत बहुत धन्यवाद!

तो मुझे एक फंक्शन चाहिए जैसे:

myfunction($products,'breville-one-touch-tea-maker-BTM800XL');
// returns 1

यहाँ ऐरे है:

$products = array (
1  => array(
        'name'          => 'The Breville One-Touch Tea Maker',
        'slug'          => 'breville-one-touch-tea-maker-BTM800XL',
        'shortname'     => 'The One-Touch Tea Maker',
        'listprice'     => '299.99',
        'price'         => '249.99',
        'rating'        => '9.5',
        'reviews'       => '81',
        'buyurl'        => 'http://www.amazon.com/The-Breville-One-Touch-Tea-Maker/dp/B003LNOPSG',
        'videoref1'     => 'xNb-FOTJY1c',
        'videoref2'     => 'WAyk-O2B6F8',
        'image'         => '812BpgHhjBML.jpg',
        'related1'      => '2',
        'related2'      => '3',
        'related3'      => '4',
        'bestbuy'       => '1',
        'quote'         => '',
        'quoteautor'    => 'K. Martino',
        ),

2  => array(
        'name'          => 'Breville Variable-Temperature Kettle BKE820XL',
        'slug'          => 'breville-variable-temperature-kettle-BKE820XL',
        'shortname'     => 'Variable Temperature Kettle',
        'listprice'     => '199.99',
        'price'         => '129.99',
        'rating'        => '9',
        'reviews'       => '78',
        'buyurl'        => 'http://www.amazon.com/Breville-BKE820XL-Variable-Temperature-1-8-Liter-Kettle/dp/B001DYERBK',
        'videoref1'     => 'oyZWBD83xeE',
        'image'         => '41y2B8jSKmwL.jpg',
        'related1'      => '3',
        'related2'      => '4',
        'related3'      => '5',
        'bestbuy'       => '1',
        'quote'         => '',
        'quoteautor'    => '',
        ),
);

जवाबों:


157

बहुत आसान:

function myfunction($products, $field, $value)
{
   foreach($products as $key => $product)
   {
      if ( $product[$field] === $value )
         return $key;
   }
   return false;
}

6
यदि आप इस फ़ंक्शन का उपयोग एक सशर्त विवरण में कर रहे हैं, तो आप इस प्रकार के विरुद्ध पूर्ण जाँच करना चाहते हैं क्योंकि लौटी हुई कुंजी में कभी-कभी एक सूचकांक हो सकता है [0]। तो अगर एक सशर्त जाँच कर रहा है, यह कुछ इस तरह दिखना चाहिए: if (myfunction($array, 'field', 'value') !== FALSE )) // do something...
एंडी कुक

159

एक और असंभव समाधान array_search()फ़ंक्शन पर आधारित है । आपको PHP 5.5.0 या उच्चतर का उपयोग करने की आवश्यकता है

उदाहरण

$userdb=Array
(
(0) => Array
    (
        (uid) => '100',
        (name) => 'Sandra Shush',
        (url) => 'urlof100'
    ),

(1) => Array
    (
        (uid) => '5465',
        (name) => 'Stefanie Mcmohn',
        (pic_square) => 'urlof100'
    ),

(2) => Array
    (
        (uid) => '40489',
        (name) => 'Michael',
        (pic_square) => 'urlof40489'
    )
);

$key = array_search(40489, array_column($userdb, 'uid'));

echo ("The key is: ".$key);
//This will output- The key is: 2

व्याख्या

फ़ंक्शन array_search()के दो तर्क हैं। पहला वह मान है जिसे आप खोजना चाहते हैं। दूसरा वह स्थान है जहाँ फ़ंक्शन को खोजना चाहिए। फ़ंक्शन array_column()को उन तत्वों के मान मिलते हैं जो कुंजी है 'uid'

सारांश

तो आप इसका उपयोग कर सकते हैं:

array_search('breville-one-touch-tea-maker-BTM800XL', array_column($products, 'slug'));

या, यदि आप पसंद करते हैं:

// define function
function array_search_multidim($array, $column, $key){
    return (array_search($key, array_column($array, $column)));
}

// use it
array_search_multidim($products, 'slug', 'breville-one-touch-tea-maker-BTM800XL');

मूल उदाहरण (xfoxawy द्वारा) डॉक्स पर पाया जा सकता है । पेज
array_column()


अपडेट करें

वाल टिप्पणी के कारण मैं जिज्ञासु था, इसलिए मैंने उपयोग array_searchकी जाने वाली विधि और स्वीकृत उत्तर पर प्रस्तावित विधि के प्रदर्शन को मापने के लिए एक सरल परीक्षा की ।

मैंने एक सरणी बनाई जिसमें 1000 सरणियाँ थीं, संरचना इस तरह थी (सभी डेटा यादृच्छिक किया गया था):

[
      {
            "_id": "57fe684fb22a07039b3f196c",
            "index": 0,
            "guid": "98dd3515-3f1e-4b89-8bb9-103b0d67e613",
            "isActive": true,
            "balance": "$2,372.04",
            "picture": "http://placehold.it/32x32",
            "age": 21,
            "eyeColor": "blue",
            "name": "Green",
            "company": "MIXERS"
      },...
]

मैंने नाम क्षेत्र के लिए विभिन्न मानों की खोज करते हुए 100 बार खोज परीक्षा चलाई, और फिर मैंने मिलीसेकंड में औसत समय की गणना की । यहां आप एक उदाहरण देख सकते हैं।

परिणाम यह थे कि इस उत्तर पर प्रस्तावित विधि को मूल्य खोजने के लिए लगभग 2E-7 की आवश्यकता थी, जबकि स्वीकृत उत्तर पद्धति को लगभग 8E-7 की आवश्यकता थी।

जैसा कि मैंने कहा कि दोनों समय से पहले इस आकार के साथ एक सरणी का उपयोग करते हुए एक आवेदन के लिए बहुत स्वीकार्य हैं। यदि आकार बहुत बढ़ता है, तो आइए 1M तत्व कहते हैं, तो यह थोड़ा अंतर भी बढ़ जाएगा।

अपडेट II

मैंने उस पद्धति के लिए एक परीक्षण जोड़ा है array_walk_recursiveजिसमें यहाँ कुछ उत्तरों पर उल्लेख किया गया था। मिला परिणाम सही है। और अगर हम प्रदर्शन पर ध्यान केंद्रित करते हैं, तो इसका परीक्षण पर परीक्षण किए गए अन्य की तुलना में थोड़ा खराब है । परीक्षण में, आप देख सकते हैं कि विधि पर आधारित विधि की तुलना में लगभग 10 गुना धीमा है array_search। फिर से, यह अधिकांश अनुप्रयोगों के लिए बहुत प्रासंगिक अंतर नहीं है।

अद्यतन III

इस पद्धति पर कई सीमाएँ निर्धारित करने के लिए @mickmackusa का धन्यवाद:

  • यह विधि साहचर्य कुंजियों पर विफल हो जाएगी।
  • यह विधि केवल अनुक्रमित सबरेज़ (0 से शुरू होने और लगातार आरोही कुंजी) पर काम करेगी।

क्या किसी को इसके प्रदर्शन का पता है? ऐसा लगता है कि यह अंततः धीमा होगा, और अभी भी 5.5 की आवश्यकता होगी। मैं 5.4 पर परीक्षण नहीं कर सकता।
वेल विक्टस

जो कोई भी समझ में नहीं आता है: php 7 में, लूप के लिए तेजी से होते हैं। जब मैं उस eval.in उदाहरण में 5.6 में बदल गया, array_search थोड़ा तेज था।
वेल विक्टस

चतुर! मैं इसी तरह का कुछ कर रहा था, array_combine () array_column () के साथ एक और सरणी बनाने के लिए जिसमें से एक ज्ञात कुंजी के साथ मेरे डेटम को हथियाने के लिए, लेकिन यह अधिक सुरुचिपूर्ण है।
डेविड

4
के array_search()साथ उपयोग करना array_column()ओपी के नमूना सरणी पर काम नहीं करेगा क्योंकि सबर्रे कीज से शुरू होती है 1। यह विधि साहचर्य कुंजियों पर भी विफल हो जाएगी। यह विधि केवल अनुक्रमित सबरेज़ पर काम करेगी (शुरुआत से 0और लगातार आरोही कुंजियाँ)। इसका कारण यह है क्योंकि array_column()इसके लौटे सरणी में नए सूचकांक उत्पन्न होंगे।
मिकमैकुसा 12

पूरी तरह से सही @mickmackusa, मैंने आपके ज्ञान को उत्तर में जोड़ दिया है। मदद के लिए धन्यवाद
Ivan Rodríguez Torres

14

यह वर्ग विधि कई स्थितियों में सरणी में खोज कर सकती है:

class Stdlib_Array
{
    public static function multiSearch(array $array, array $pairs)
    {
        $found = array();
        foreach ($array as $aKey => $aVal) {
            $coincidences = 0;
            foreach ($pairs as $pKey => $pVal) {
                if (array_key_exists($pKey, $aVal) && $aVal[$pKey] == $pVal) {
                    $coincidences++;
                }
            }
            if ($coincidences == count($pairs)) {
                $found[$aKey] = $aVal;
            }
        }

        return $found;
    }    
}

// Example:

$data = array(
    array('foo' => 'test4', 'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test1', 'bar' => 'baz3'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz4'),
    array('foo' => 'test4', 'bar' => 'baz1'),
    array('foo' => 'test',  'bar' => 'baz1'),
    array('foo' => 'test3', 'bar' => 'baz2'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test',  'bar' => 'baz'),
    array('foo' => 'test4', 'bar' => 'baz1')
);

$result = Stdlib_Array::multiSearch($data, array('foo' => 'test4', 'bar' => 'baz1'));

var_dump($result);

उत्पादन करेंगे:

array(2) {
  [5]=>
  array(2) {
    ["foo"]=>
    string(5) "test4"
    ["bar"]=>
    string(4) "baz1"
  }
  [10]=>
  array(2) {
    ["foo"]=>
    string(5) "test4"
    ["bar"]=>
    string(4) "baz1"
  }
}

हाय भाग्यवादी stackoverflow.com/questions/40860030/... । इन सवालों के जवाब में यह बताया गया है कि आप कृपया उस प्रश्न को स्पष्ट कर सकते हैं
KARTHI SRV

4

इस फ़ंक्शन का उपयोग करें:

function searchThroughArray($search,array $lists){
        try{
            foreach ($lists as $key => $value) {
                if(is_array($value)){
                    array_walk_recursive($value, function($v, $k) use($search ,$key,$value,&$val){
                        if(strpos($v, $search) !== false )  $val[$key]=$value;
                    });
            }else{
                    if(strpos($value, $search) !== false )  $val[$key]=$value;
                }

            }
            return $val;

        }catch (Exception $e) {
            return false;
        }
    }

और कॉल फ़ंक्शन।

print_r(searchThroughArray('breville-one-touch-tea-maker-BTM800XL',$products));

अच्छा उत्तर। आप मेरे प्रस्ताव पर अपने प्रस्ताव के प्रदर्शन की जांच कर सकते हैं
इवान रोड्रिगेज टोरेस

कोड-केवल उत्तर StackOverflow पर कम मान हैं। कृपया यह जानने के लिए कि आपका पत्ता-नोड विकल्प खोज फ़ंक्शन कैसे काम करता है, अपनी पोस्ट को अपडेट करें। यह विधि विशेष रूप से काम करने के लिए डिज़ाइन नहीं की गई है क्योंकि ओपी पूछ रहा है, इसलिए मतभेदों को स्पष्ट करना महत्वपूर्ण है। एक डेमो लिंक पाठक की समझ में बहुत सुधार करेगा। हमेशा ओपी और अधिक से अधिक एसओ दर्शकों को शिक्षित करने के इरादे से उत्तर पोस्ट करें।
मिकमैकुसा

1
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; 
} 

कोड-केवल उत्तर StackOverflow पर कम मान हैं। कृपया अपने पोस्ट को अपडेट करके बताएं कि आपकी पुनरावर्ती विधि कैसे काम करती है, ऐसी परिस्थितियां जहां यह उचित है, और ऐसी स्थितियां जहां पुनरावृत्ति अनावश्यक उपरि है। हमेशा ओपी और अधिक से अधिक एसओ दर्शकों को शिक्षित करने के इरादे से उत्तर पोस्ट करें।
मिकमैकुसा

1

आने वाले अगले आगंतुक के लिए: पुनरावर्ती सरणी चलना का उपयोग करें; यह बहुआयामी सरणी में हर "पत्ती" पर जाता है। यहाँ प्रेरणा के लिए है:

function getMDArrayValueByKey($a, $k) {
    $r = [];
    array_walk_recursive ($a, 
                          function ($item, $key) use ($k, &$r) {if ($key == $k) $r[] = $item;}
                          );
    return $r;
}

कोई दिक्कत नहीं है! बस आपको समय बचाने के लिए, यदि आप उत्तर देने की कोशिश करते हैं, तो फ़ंक्शन एक तत्व के साथ एक सरणी देता है। कुंजी वांछित उत्तर है :)
Iván Rodríguez Torres

@ इवान जोसेफ का जवाब इस एक से बहुत अलग है। क्या आपने खुद यह परीक्षण किया। मैं इस उत्तर को ध्यान में रख रहा हूं और मुझे नहीं लगता कि यह काम कर सकता है क्योंकि array_walk_recursive एक स्तर नहीं देख सकता है। प्रत्येक प्रथम स्तर की कुंजी के लिए, josef स्ट्रैप्स को कॉल कर रहा है या सभी लीफ्नोड्स की जांच कर रहा है। फर्क देखें?
मिकमैकुसा

बेशक @mickmackusa लेकिन हंस किसी तरह की प्रेरणा दे रहा है, इसका जवाब वस्तुतः समाधान नहीं दे रहा है। इसे और विस्तार की जरूरत है, जैसा कि जोसेफ ने अपने जवाब में किया था। लेकिन, आप इस बिंदु पर सही हैं कि यह उत्तर पूरी तरह से समस्या का समाधान नहीं करता है।
Iván Rodríguez Torres

1

मैं नीचे की तरह करना चाहूंगा, जहां $productsशुरुआत में समस्या में वास्तविक सरणी दी गई है।

print_r(
  array_search("breville-variable-temperature-kettle-BKE820XL", 
  array_map(function($product){return $product["slug"];},$products))
);

0

इसे इस्तेमाल करे

function recursive_array_search($needle,$haystack) {
        foreach($haystack as $key=>$value) {
            $current_key=$key;
            if($needle==$value['uid'] OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
                return $current_key;
            }
        }
        return false;
    }

कोड-केवल उत्तर StackOverflow पर कम मान हैं। कृपया अपने पोस्ट को अपडेट करके बताएं कि आपकी पुनरावर्ती विधि कैसे काम करती है, ऐसी परिस्थितियां जहां यह उचित है, और ऐसी स्थितियां जहां पुनरावृत्ति अनावश्यक उपरि है। हमेशा ओपी और अधिक से अधिक एसओ दर्शकों को शिक्षित करने के इरादे से उत्तर पोस्ट करें। पीएस मुझे लगता है कि सबसे php डेवलपर्स का चुनाव करेगा, &&और ||के बजाय ANDऔर ORअपनी हालत में। घोषित करने का कोई कारण नहीं है current_key। पर तुलना $needleसख्त होनी चाहिए।
मिकमैकुसा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.