PHP - वस्तुओं के एक समूह से वस्तु संपत्ति द्वारा प्रविष्टि पाते हैं


174

सरणी ऐसा दिखता है:

[0] => stdClass Object
        (
            [ID] => 420
            [name] => Mary
         )

[1] => stdClass Object
        (
            [ID] => 10957
            [name] => Blah
         )
...

और मेरे पास एक पूर्णांक चर कहा जाता है $v

मैं एक ऐरे एंट्री का चयन कैसे कर सकता हूं जिसके पास एक ऑब्जेक्ट है जहां IDसंपत्ति का $vमूल्य है?

जवाबों:


189

आप या तो सरणी को पुनरावृत्त करते हैं, विशेष रिकॉर्ड के लिए खोज करते हैं (केवल एक बार में ही खोज करते हैं) या किसी अन्य साहचर्य सरणी का उपयोग करके हैशमैप का निर्माण करते हैं।

पूर्व के लिए, कुछ इस तरह

$item = null;
foreach($array as $struct) {
    if ($v == $struct->ID) {
        $item = $struct;
        break;
    }
}

इस सवाल और बाद के जवाबों को बाद में अधिक जानकारी के लिए देखें - कई अनुक्रमित द्वारा संदर्भ PHP सरणी


3
शून्य करने के लिए $ आइटम सेट करने की आवश्यकता नहीं है।
dAm2K 20

32
उफ़, वहाँ यह है :) कि मामले में मांग की गई वस्तु सरणी में नहीं है। वैकल्पिक रूप से, आप उपयोग कर सकते हैं isset($item)लेकिन मैं ठीक से चर शुरू करना पसंद करता हूं
फिल

3
आप में से उन लोगों के लिए, जिनके पास स्ट्रिंग्स के उपयोग के लिए महत्वपूर्ण मूल्य हैंif($v == $struct["ID"]){...
wadart

67

YurkamTim सही है। इसे केवल एक संशोधन की आवश्यकता है:

फ़ंक्शन ($) के बाद आपको "उपयोग (और $ searchValue)" द्वारा बाहरी चर के लिए एक संकेतक की आवश्यकता होती है और फिर आप बाहरी चर का उपयोग कर सकते हैं। इसके अलावा आप इसे संशोधित कर सकते हैं।

$neededObject = array_filter(
    $arrayOfObjects,
    function ($e) use (&$searchedValue) {
        return $e->id == $searchedValue;
    }
);

2
आप संशोधन के बारे में सही हैं और यह एक साफ तरीका है, लेकिन मैंने ऑब्जेक्ट के माध्यम से पुनरावृत्ति करने की तुलना में गति का परीक्षण किया - अपने आप से, क्योंकि @ एफिल की तरह, array_filter यह भी कर रहा है - और यह विधि लगभग पांच ले रही है अधिक समय। मेरी परीक्षा की वस्तु कोई बड़ी नहीं है, ताकि यह और भी खराब हो जाए।
निकोलाई

9
&जब आयात करने की आवश्यकता नहीं है $searchedValueबंद दायरे में। इसका &उपयोग एक संदर्भ बनाने के लिए किया जाता है जो केवल तभी आवश्यक है जब $searchedValueक्लोजर के अंदर संशोधित किया गया हो।
स्टीफन गेहरिग

यह अच्छा है। मुझे नहीं पता था कि PHP ऐसी चीजें कर सकती है। मैंने सोचा globalथा कि कार्यों में डेटा साझा करना ही एकमात्र प्रयोग था! लेकिन अगर यह वास्तव में धीमा है तो अफ़सोस की बात है। :(
NoOne

13
TS ने एकल प्रविष्टि के लिए कहा, यह कोड एक सरणी देता है।
पावेल वेलासोव

57
$arr = [
  [
    'ID' => 1
  ]
];

echo array_search(1, array_column($arr, 'ID')); // prints 0 (!== false)

3
निश्चित नहीं कि यह पसंदीदा उत्तर क्यों नहीं है। क्या यह इसलिए है क्योंकि आप दो कार्य कह रहे हैं?
१३18

1
मुझे लगता है कि मैं पार्टी के लिए बहुत देर हो चुकी थी;) इसकी कमी और पठनीयता बिना किसी लूप और ब्रेक के इसे उचित बनाएगी। लेकिन अभी तक इसे बेंचमार्क नहीं किया है। आपके पास PHP में बहुत सारे विकल्प हैं ताकि आप इसे प्राप्त कर सकें।
टिम

3
बहुत ही सुंदर समाधान। पीएचपी में वस्तुओं की एक सरणी के साथ भी काम करता है। PHP 7 के लिए: array_search ($ ऑब्जेक्ट-> आईडी, array_column ($ ऑब्जेक्ट, 'आईडी'));
माइक

3
यह पसंदीदा उत्तरदाता नहीं है क्योंकि ऑप ऑब्जेक्ट की सरणी के लिए पूछता है और यह उत्तर केवल शुद्ध सरणियों को संभालता है।
द्विज

8
यह सही नहीं है। यह कोड ऑब्जेक्ट्स / नॉन फ्लैट एरे को संभालता है
टिम

31

मैंने यहां अधिक सुरुचिपूर्ण समाधान पाया है । प्रश्न के अनुकूल होने पर ऐसा लग सकता है:

$neededObject = array_filter(
    $arrayOfObjects,
    function ($e) use ($searchedValue) {
        return $e->id == $searchedValue;
    }
);

16
+1 लेकिन array_filterएक सरणी लौटाता है, और पहले मूल्य पर नहीं मिलेगा।
कार्लोस कैंपडरो जूल

4
यह $searchedValueफ़ंक्शन के अंदर पहचान नहीं कर रहा है। लेकिन इसके बाहर है।
एम। अहमद ज़फ़र

4
शुरुआत के लिए, यह कोड काम नहीं करता है क्योंकि $searchedValueक्लोजर दायरे से बाहर है। दूसरे, आपको कैसे लगता है कि ये ऐरे तरीके काम करते हैं? वे सभी सरणी पर आंतरिक रूप से लूप करते हैं
फिल

1
मल्टी कोर के समय में, यह - अन्य प्रोग्रामिंग वातावरणों में दुर्भाग्य से - समानांतर में संसाधित किया जा सकता है, जरूरी नहीं कि ऊपर लूप
फ्लोइथ्रीपवुड

3
$searchedValueजरूरत लिखने के लिए उपयोग करने के लिएfunction ($e) use ($searchedValue) {
विल्लिंट्रेन्टर्ट

20

यदि आपको कई बार खोजने की आवश्यकता है, तो पुनः अनुक्रमित करने के लिए array_column का उपयोग करने से समय की बचत होगी:

$lookup = array_column($arr, NULL, 'id');   // re-index by 'id'

तब आप बस $lookup[$id]इच्छा कर सकते हैं ।


3
यह सबसे आश्चर्यजनक जवाब था, भले ही यह सबसे सहज न हो ...
थियागो नटानाएल

11
class ArrayUtils
{
    public static function objArraySearch($array, $index, $value)
    {
        foreach($array as $arrayInf) {
            if($arrayInf->{$index} == $value) {
                return $arrayInf;
            }
        }
        return null;
    }
}

इसका उपयोग करना चाहते हैं जिस तरह से आप कुछ इस तरह होगा:

ArrayUtils::objArraySearch($array,'ID',$v);

9

प्रयत्न

$entry = current(array_filter($array, function($e) use($v){ return $e->ID==$v; }));

यहाँ काम कर रहे उदाहरण


1
बहुत उपयोगी है! धन्यवाद भाई!
फर्नांडो लियोन

यह पहले पाए गए तत्व पर नहीं रुकेगा, क्या ऐसा होगा?
य्यूगेंका

7

@YurkaTim की एक छोटी सी गलती को ठीक करते हुए , आपका समाधान मेरे लिए काम करता है use:

$searchedValueफ़ंक्शन के अंदर उपयोग करने के लिए , एक समाधान use ($searchedValue)फ़ंक्शन पैरामीटर के बाद हो सकता है function ($e) HERE

array_filterसमारोह केवल पर लौट $neededObjectयदि वापसी पर शर्त हैtrue

यदि $searchedValueएक स्ट्रिंग या पूर्णांक है:

$searchedValue = 123456; // Value to search.
$neededObject = array_filter(
    $arrayOfObjects,
    function ($e) use ($searchedValue) {
        return $e->id == $searchedValue;
    }
);
var_dump($neededObject); // To see the output

अगर $searchedValueवह सरणी है जहां हमें सूची के साथ जांच की आवश्यकता है:

$searchedValue = array( 1, 5 ); // Value to search.
$neededObject  = array_filter(
    $arrayOfObjects,
    function ( $e ) use ( $searchedValue ) {
        return in_array( $e->term_id, $searchedValue );
    }
);
var_dump($neededObject); // To see the output

1
मुझे लगता है कि अंतिम पंक्ति होनी चाहिए var_dump($neededObject);:)
शालिक

3

कभी-कभी मुझे खोज करने के लिए array_reduce () फ़ंक्शन का उपयोग करना पसंद है । यह array_filter () के समान है, लेकिन खोजे गए सरणी को प्रभावित नहीं करता है, जिससे आप एक ही सरणी के ऑब्जेक्ट पर कई खोज कर सकते हैं।

$haystack = array($obj1, $obj2, ...); //some array of objects
$needle = 'looking for me?'; //the value of the object's property we want to find

//carry out the search
$search_results_array = array_reduce(
  $haystack,

  function($result_array, $current_item) use ($needle){
      //Found the an object that meets criteria? Add it to the the result array 
      if ($current_item->someProperty == $needle){
          $result_array[] = $current_item;
      }
      return $result_array;
  },
  array() //initially the array is empty (i.e.: item not found)
);

//report whether objects found
if (count($search_results_array) > 0){
  echo "found object(s): ";
  print_r($search_results_array[0]); //sample object found
} else {
  echo "did not find object(s): ";
}

1
आपके पास अपनी स्थिति के अंदर एक टाइपो है जहाँ आप योग को जोड़ रहे हैं results_array। : यह इस होना चाहिएif ($current_item->someProperty == $needle){ $result_array[] = $current_item; }
adrum

समायोजित। धन्यवाद @adrum!
युविलियो

1

मैंने जावा कीमैप के कुछ प्रकार के साथ ऐसा किया। यदि आप ऐसा करते हैं, तो आपको हर बार अपने ऑब्जेक्ट सरणी पर लूप करने की आवश्यकता नहीं है।

<?php

//This is your array with objects
$object1 = (object) array('id'=>123,'name'=>'Henk','age'=>65);
$object2 = (object) array('id'=>273,'name'=>'Koos','age'=>25);
$object3 = (object) array('id'=>685,'name'=>'Bram','age'=>75);
$firstArray = Array($object1,$object2);
var_dump($firstArray);

//create a new array
$secondArray = Array();
//loop over all objects
foreach($firstArray as $value){
    //fill second        key          value
    $secondArray[$value->id] = $value->name;
}

var_dump($secondArray);

echo $secondArray['123'];

उत्पादन:

array (size=2)
  0 => 
    object(stdClass)[1]
      public 'id' => int 123
      public 'name' => string 'Henk' (length=4)
      public 'age' => int 65
  1 => 
    object(stdClass)[2]
      public 'id' => int 273
      public 'name' => string 'Koos' (length=4)
      public 'age' => int 25
array (size=2)
  123 => string 'Henk' (length=4)
  273 => string 'Koos' (length=4)
Henk

आह, आईडी द्वारा सरणी reindexing! मैं आमतौर पर ऐसा करता हूं और यह चीजों को अच्छा बनाता है।
Kzqai

1

पहला मूल्य तुरंत प्राप्त करने का तरीका:

$neededObject = array_reduce(
    $arrayOfObjects,
    function ($result, $item) use ($searchedValue) {
        return $item->id == $searchedValue ? $item : $result;
    }
);

0

मैंने एक त्वरित द्विआधारी खोज एल्गोरिथ्म का उपयोग करते हुए यहां इस समस्या को कुशलतापूर्वक हल करने के लिए क्या पोस्ट किया है: https://stackoverflow.com/a/52786742/1678210

मैं एक ही जवाब की नकल नहीं करना चाहता था। किसी और ने इसे थोड़ा अलग तरीके से पूछा था लेकिन जवाब एक ही है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.