2009-11-03 18 views
8

एक पैटर्न जो मैं अक्सर विकसित करते समय चलाता हूं, ऑब्जेक्ट्स के संग्रह से ऑब्जेक्ट्स के संग्रह से कॉलम/विशेषता मान एकत्र करने का प्रयास कर रहा है। उदाहरण के लिए:एक ऐरे में कॉलम मान एकत्रित करना

$ids = array(); 
foreach ($documents as $document) { 
    $ids[] = $document->name; 
} 

क्या मैं अकेला हूं जो इसमें चलता है? और क्या पीएचपी को कम लाइनों में हल करने का कोई तरीका है? मैंने देखा लेकिन कुछ भी नहीं मिला।

चूंकि मैं एक एमवीसी फ्रेमवर्क का उपयोग करता हूं, मेरे पास बेसयूल्ट क्लास तक पहुंच है जिसमें सामान्य कार्य होते हैं जो वास्तव में किसी भी विशिष्ट वर्ग में फिट नहीं होते हैं। एक समाधान एक सह कार्यकर्ता द्वारा प्रस्तावित है:

class BaseUtil 
{ 
    public static function collect($collection, $property) { 
     $values = array(); 
     foreach ($collection as $item) { 
      $values[] = $item->{$property}; 
     } 
     return $values; 
    } 
} 

तब मैं सिर्फ कर सकते हैं: भी जर्जर

$ids = BaseUtil::collect($documents, 'name'); 

नहीं। किसी और के पास कोई अन्य विचार है? और क्या मैं पागल हूं या ऐसा लगता है कि PHP को बहुत समय पहले हल होना चाहिए था?

उत्तर

10

आप इस उद्देश्य के लिए array_map() फ़ंक्शन का उपयोग कर सकते हैं:

function getName($obj) { 
    return $obj->name; 
} 

$documentsName = array_map("getName", $documents); 

तुम भी create_function() समारोह लैम्ब्डा कार्यों के लिए विचार कर सकते हैं अगर आप डॉन ' टी वैश्विक नामस्थान में getName() फ़ंक्शन बनाना चाहते हैं।

में पीएचपी 5.3 आप भी कर सकते हैं:

$documentsName = array_map(function ($obj) { return $obj->name; }, $documents); 
+0

यह मेरे उद्देश्यों के लिए काम नहीं करेगा क्योंकि मैं किसी भी संपत्ति/विशेषता के लिए इसे सामान्य बनाना चाहता हूं; सिर्फ नाम के लिए नहीं। ऐसा करने की कोशिश करते समय array_map() बहुत अधिक गन्दा हो जाता है और मैं इसे काम नहीं कर सका। –

+0

@ जस्टिन वेलेंटीनी इसे गन्दा नहीं होना चाहिए: '$ name =" foobar "; array_map (फ़ंक्शन ($ obj) उपयोग ($ नाम) {वापसी $ obj -> {$ name};}, $ दस्तावेज़); ' – Andrea

+0

इसके अलावा, 'create_function' का उपयोग करना एक बुरा विचार है। अब कोई भी PHP 5.2 का उपयोग नहीं कर रहा है - यदि वे हैं, तो यह एक गंभीर सुरक्षा समस्या है। इसके बजाय एक बंद का उपयोग करें। – Andrea

1

एक और दृष्टिकोण के रूप में एक भाषा है कि यह बहुत अर्थपूर्ण नहीं है "अमीर" सरणी वस्तुओं, उदाहरण के

class Ary extends ArrayObject 
    { 
     function pluck($key) { 
      $a = array(); 
      foreach($this as $sub) $a[] = $sub[$key]; 
      return new self($a); 
     } 

     function join($delim = ',') { 
      return implode($delim, (array) $this); 
     } 

     static function init($ary) { 
      return new self($ary); 
     } 
    } 

    echo 
     Ary::init(array(
     array('foo', 'bar'), array('baz', 'quux') 
    ))->pluck(1)->join(); 
0

PHP के कमजोरियों में से एक के लिए अन्य भाषाओं

में पाई जाने वाली उपयोग करने के लिए है।

रूबी या पर्ल जैसी भाषाओं में आप शायद इस डेटा को कोड की एक पंक्ति के साथ प्राप्त कर सकते हैं, आपको आमतौर पर वांछित परिणाम प्राप्त करने के लिए पोस्ट किए गए छोटे एल्गोरिदम की आवश्यकता होती है।

मैं आपके पास जो कुछ भी रखता हूं उसके साथ रहना चाहता हूं, लेकिन यहां केवल एक और दृष्टिकोण है।

class BaseUtil 
{ 
    public static function collect($collection, $property) 
    { 
     array_walk($collection, array(__CLASS__, 'reduceObject'), $property); 
     return $collection; 
    } 

    public static function reduceObject(&$object, $index, $property) 
    { 
     $object = $object->{$property}; 
    } 
} 
+0

आपको PHP में संदर्भों के रूप में कक्षाएं पारित करने की आवश्यकता नहीं है, वे डिफ़ॉल्ट रूप से हैं। – Cobby

0

इनपुट लोगों के लिए धन्यवाद। मुझे लगता है कि मैं सिर्फ अपनी सहकर्मी के समाधान का उपयोग करने जा रहा हूँ:

class BaseUtil 
{ 
    public static function collect($collection, $property) { 
     $values = array(); 
     foreach ($collection as $item) { 
      $values[] = $item->{$property}; 
     } 
     return $values; 
    } 
} 
0

एक Magento संग्रह लोड हो रहा है, और कहा कि संग्रह में फिर से पाशन तो आप एक सरणी यह ​​अप्रभावी है में अपने वांछित मान जोड़ सकते हैं की तुलना में। ऐसा करने का उचित तरीका getColumnValues ​​() विधि का उपयोग कर रहा है। यह विधि कॉलम नाम निर्दिष्ट करके आपको मूल्यों की एक सरणी देगी।

यह करने का उचित तरीका यहां है।

$collection =Mage::getModel('your/object')->getCollection() 
         ->addFieldToSelect('customer_id'); 

$yourArray = $collection->getColumnValues('customer_id'); 

यह आपको आपके द्वारा चुने गए सभी ग्राहक_आईडी मानों के साथ एक सरणी देगा।

3

आप ouzo goodies

$names = array_map(Functions::extract()->name, $documents); 

साथ या सरणी (ouzo से उपहार) के साथ आसानी से यह कर सकते हैं

$names = Arrays::map($documents, Functions::extract()->name); 

तुम भी तरीकों में से एकत्रित फ़ील्ड निकाल सकते हैं कॉल या सरणी का उपयोग आदि:

$names = Arrays::map($documents, Functions::extract()->getAuthor()->roles[0]); 

चेक आउट: http://ouzo.readthedocs.org/en/latest/utils/functions.html#extract

ouzo के साथ कार्यात्मक प्रोग्रामिंग भी देखें (मैं एक लिंक पोस्ट नहीं कर सकता)।

संबंधित मुद्दे