2012-07-19 23 views
13

मुझे पेर्ल के मानचित्र() फ़ंक्शन में उपयोग किया जाता है जहां कॉलबैक कुंजी और मान दोनों को असाइन कर सकता है, इस प्रकार एक सहयोगी सरणी बना सकता है जहां इनपुट एक फ्लैट सरणी था। मुझे array_fill_keys() से अवगत है जो उपयोगी हो सकता है यदि आप जो करना चाहते हैं वह एक शब्दकोश-शैली हैश बना रहा है, लेकिन क्या होगा यदि आप जरूरी नहीं कि सभी मान समान हों? स्पष्ट रूप से सभी चीजों को फ़ोरैच पुनरावृत्ति के साथ किया जा सकता है, लेकिन अन्य (संभवतः अधिक सुरुचिपूर्ण) विधियां मौजूद हैं?एक एसोसिएटिव सरणी में सरणी या ऑब्जेक्ट्स की सरणी को कैसे परिवर्तित करें?

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

$original_array: ('a', 'b', 'c', 'd') 
$new_hash: ('a'=>'yes', 'b'=>'no', 'c'=>'yes', 'd'=>'no') 

*note: the values in this example are arbitrary, governed by some business logic that is not really relevant to this question. For example, perhaps it's based on the even-oddness of the ordinal value of the key 

वास्तविक दुनिया उदाहरण तो, एक जवाब है कि यहां प्रदान की गई थी, तो यहां आप केवल उन इनपुट फ़ील्ड है कि किसी भी मानदंड से मेल खाते की एक सूची प्राप्त करने के लिए $ _POST के द्वारा पार्स सकता है का उपयोग कर। यह उपयोगी हो सकता है, उदाहरण के लिए, यदि आपके पास अपने फॉर्म में बहुत से इनपुट फ़ील्ड हैं, लेकिन उनमें से एक निश्चित समूह को एक साथ संसाधित किया जाना चाहिए।

इस मामले में मेरे पास कई इनपुट फ़ील्ड हैं जो डेटाबेस में मैपिंग का प्रतिनिधित्व करते हैं। प्रत्येक इनपुट फ़ील्ड इस तरह दिखता है: <input name="field-user_email" value="2" /> जहां इस प्रकार के प्रत्येक फ़ील्ड को "फ़ील्ड-" के साथ उपसर्ग किया गया है।

हम जो करना चाहते हैं वह है, सबसे पहले, केवल उन इनपुट फ़ील्ड की सूची प्राप्त करें जो वास्तव में "फ़ील्ड-" से शुरू होते हैं, फिर हम $mapped_fields नामक एक सहयोगी सरणी बनाना चाहते हैं जिसमें निकाले गए फ़ील्ड का नाम कुंजी के रूप में है और मूल्य के रूप में वास्तविक इनपुट फ़ील्ड का मान।

$mapped_fields = array_reduce(preg_grep('/field-.+/', array_keys($_POST)), function($hash, $field){ $hash[substr($field, 6)] = $_POST[$field]; return $hash; }); 

आउटपुट कौन सा:

Array ([date_of_birth] => 1 [user_email] => 2 [last_name] => 3 [first_name] => 4 [current_position] => 6) 

(तो, सिर्फ कहने वाले लोगों को रोकने के लिए, मुझे इस बात से सहमत यकीनन बहुत कम पढ़ी जा सकती है कि कॉम्पैक्ट कोड के इस बिट है कि एक साधारण पाश कि $ _POST के माध्यम से दोहराता और, प्रत्येक कुंजी के लिए, यह देखने के लिए जांचता है कि इसमें उपसर्ग है या नहीं, और यदि ऐसा है, तो उसे और उसके मान को सरणी पर पॉप करता है)

+0

क्या आप सरणी का डंप पोस्ट कर सकते हैं ('print_r' या' var_dump' का उपयोग करके)? – Florent

+1

@ फ्लोरंट किया गया ... –

उत्तर

29

मैं ठीक उसी समस्या थी कुछ दिन पहले। array_map का उपयोग करना संभव नहीं है, लेकिन array_reduce चाल है।

$arr = array('a','b','c','d'); 
$assoc_arr = array_reduce($arr, function ($result, $item) { 
    $result[$item] = (($item == 'a') || ($item == 'c')) ? 'yes' : 'no'; 
    return $result; 
}, array()); 
var_dump($assoc_arr); 

परिणाम:

array(4) { ["a"]=> string(3) "yes" ["b"]=> string(2) "no" ["c"]=> string(3) "yes" ["d"]=> string(2) "no" }

+1

वाह, इस तरह से array_reduce का उपयोग करने के लिए यह कभी नहीं हुआ - यह पता लगाना कि यह हमेशा एक स्केलर मान वापस करने के लिए था। पूर्व-निरीक्षण में, यह तर्कसंगत है कि क्या यह दृष्टिकोण उपर्युक्त विधि @minitech उल्लेखों के लिए बेहतर है। लेकिन आपका विकल्प देखना बहुत अच्छा है! पोस्ट करने का शुक्रिया। –

+0

चालाक विधि। यह अक्सर बहुत आसान – Ikke

+0

आता है मैं वास्तव में टॉम ऑग्रेर से सहमत हूं, यह संदिग्ध है अगर किसी को इस विधि का उपयोग करना चाहिए। यहां तक ​​कि यदि आप प्रदर्शन पक्ष (जो मुझे यकीन नहीं है) पर जीतते हैं, तो आप सामान्य फोरैच स्टेटमेंट की तुलना में पठनीयता को खो देते हैं। हालांकि सुरुचिपूर्ण;) –

2

जहां तक ​​मुझे पता है, यह एक अभिव्यक्ति में पूरी तरह असंभव है, तो आप अच्छी तरह से foreach लूप का उपयोग करें, à la

$new_hash = array(); 

foreach($original_array as $item) { 
    $new_hash[$item] = 'something'; 
} 

आप एक अभिव्यक्ति में यह जरूरत है, आगे जाना है और एक समारोह बनाने:

function array_map_keys($callback, $array) { 
    $result = array(); 

    foreach($array as $item) { 
     $r = $callback($item); 

     $result[$r[0]] = $r[1]; 
    } 

    return $result; 
} 
2

यह स्वीकार कर लिया विधि में मेरी टिप्पणी पर एक स्पष्टीकरण है। उम्मीद है कि पढ़ने के लिए आसान है।यह एक वर्डप्रेस वर्ग से है, इस प्रकार $ wpdb संदर्भ डेटा लिखने के लिए:

class SLPlus_Locations { 
    private $dbFields = array('name','address','city'); 

    public function MakePersistent() { 
     global $wpdb; 
     $dataArray = array_reduce($this->dbFields,array($this,'mapPropertyToField')); 
     $wpdb->insert('wp_store_locator',$dataArray); 
    } 

    private function mapPropertyToField($result,$property) { 
     $result[$property] = $this->$property; 
     return $result; 
    } 
} 

जाहिर है एक सा पूर्ण समाधान के लिए और अधिक है, लेकिन array_reduce के लिए प्रासंगिक भागों() मौजूद हैं। पढ़ने के लिए आसान और foreach से अधिक सुरुचिपूर्ण या array_map() के साथ मुद्दे को एक कस्टम डालने कथन के माध्यम से मजबूर करना।

अच्छा!

+0

एक-लाइनर और पर्ल-स्टाइल ओबफू कोड के लिए एक चूसने वाला होने के नाते, यह उत्पादन परियोजनाओं में भी मेरा जाने-माने समाधान रहा है। अच्छा है, और एक और समाधान प्रदान करने के लिए वापस आने के लिए धन्यवाद। –

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