2012-06-28 12 views
9
साथ एक सरणी से एक बहुआयामी सरणी बनाएँ

संभव डुप्लिकेट:
Converting an array from one to multi-dimensional based on parent ID valuesपीएचपी संबंधपरक डेटा

मैं PHP में काम कर रहा हूँ।

मेरे पास निम्न सरणी है जिसमें डेटा (अभिभावक बाल संबंध) संबंध हैं।

Array   
(  
    [5273] => Array   
     (  
      [id] => 5273   
      [name] => John Doe   
      [parent] =>   
     )   

    [6032] => Array   
     (  
      [id] => 6032   
      [name] => Sally Smith   
      [parent] => 5273   
     )   

    [6034] => Array   
     (  
      [id] => 6034   
      [name] => Mike Jones   
      [parent] => 6032   
     )   

    [6035] => Array   
     (  
      [id] => 6035   
      [name] => Jason Williams   
      [parent] => 6034   
     )   

    [6036] => Array   
     (  
      [id] => 6036   
      [name] => Sara Johnson   
      [parent] => 5273   
     )   

    [6037] => Array   
     (  
      [id] => 6037   
      [name] => Dave Wilson   
      [parent] => 5273   
     )   

    [6038] => Array   
     (  
      [id] => 6038   
      [name] => Amy Martin   
      [parent] => 6037   
     )   
)   

मैं इसे इस JSON प्रारूप में होने की जरूरत है:

{   
    "id":"5273",   
    "name":"John Doe",   
    "data":{   

    },   
    "children":[   
     {   
     "id":" Sally Smith",   
     "name":"6032",   
     "data":{   

     },   
     "children":[   
      {   
       "id":"6034",   
       "name":"Mike Jones",   
       "data":{   

       },   
       "children":[   
        {   
        "id":"6035",   
        "name":"Jason Williams",   
        "data":{   

        },   
        "children":[   
         {   
          "id":"node46",   
          "name":"4.6",   
          "data":{   

          },   
          "children":[   

          ]   
         }   
        ]   
        }   
       ]   
      },   
      {   
       "id":"6036",   
       "name":"Sara Johnson",   
       "data":{   

       },   
       "children":[   

       ]   
      },   
      {   
       "id":"6037",   
       "name":"Dave Wilson",   
       "data":{   

       },   
       "children":[   
        {   
        "id":"6038",   
        "name":"Amy Martin",   
        "data":{   

        },   
        "children":[   

        ]   
        }   
       ]   
      }   
     ]   
     }   
    ]   
}   

मैं जानता हूँ कि मैं एक बहुआयामी सरणी बना सकते हैं और json_encode के माध्यम से इसे चलाने के लिए() की जरूरत है। मुझे यह भी विश्वास है कि ऐसा करने के लिए उपयोग की जाने वाली इस विधि को रिकर्सिव होने की आवश्यकता है क्योंकि वास्तविक दुनिया के डेटा में अज्ञात स्तर हो सकते हैं।

मुझे अपने कुछ दृष्टिकोण दिखाने में खुशी होगी लेकिन उन्होंने काम नहीं किया है।

क्या कोई मेरी मदद कर सकता है?

मुझे अपना काम साझा करने के लिए कहा गया था। मैंने यही कोशिश की है, लेकिन मुझे यह नहीं मिला है कि मुझे पता नहीं है कि यह कितना उपयोगी है।

मैंने केवल संबंधों की एक सरणी बनाई।

foreach($array as $k => $v){ 
    $relationships[$v['id']] = $v['parent']; 
} 

मुझे लगता है कि (एक और एसओ पद पर आधारित) एक नई बहुआयामी सरणी बनाने के लिए इस संबंधपरक डेटा का इस्तेमाल किया। इस मैं सही "बच्चों" लेबल आदि

$childrenTable = array(); 
    $data = array(); 
    foreach ($relationships as $n => $p) { 
     //parent was not seen before, put on root 
     if (!array_key_exists($p, $childrenTable)) { 
      $childrenTable[$p] = array(); 
      $data[$p] = &$childrenTable[$p]; 
     } 
     //child was not seen before 
     if (!array_key_exists($n, $childrenTable)) { 
      $childrenTable[$n] = array(); 
     } 
     //root node has a parent after all, relocate 
     if (array_key_exists($n, $data)) { 
      unset($data[$n]); 
     } 
     $childrenTable[$p][$n] = &$childrenTable[$n];  
    } 
    unset($childrenTable); 

print_r($data); 
+0

आपके द्वारा पोस्ट किया गया प्रारंभिक प्रारूप * एक बहुआयामी सरणी है। क्या वह जेसन एन्कोड में काम नहीं करना चाहिए? –

+0

बेन रूक्स, हां, यह एक बहुआयामी सरणी है लेकिन यह JSON उत्पन्न करने के लिए सही प्रारूप में नहीं है। – maestrojed

+0

आपने क्या प्रयास किया है? अपना कोड पोस्ट करें कि आप सरणी तैयार कर रहे हैं। – Sanjay

उत्तर

12
<?php 
header('Content-Type: application/json; charset="utf-8"'); 

/** 
* Helper function 
* 
* @param array $d flat data, implementing a id/parent id (adjacency list) structure 
* @param mixed $r root id, node to return 
* @param string $pk parent id index 
* @param string $k id index 
* @param string $c children index 
* @return array 
*/ 
function makeRecursive($d, $r = 0, $pk = 'parent', $k = 'id', $c = 'children') { 
    $m = array(); 
    foreach ($d as $e) { 
    isset($m[$e[$pk]]) ?: $m[$e[$pk]] = array(); 
    isset($m[$e[$k]]) ?: $m[$e[$k]] = array(); 
    $m[$e[$pk]][] = array_merge($e, array($c => &$m[$e[$k]])); 
    } 

    return $m[$r][0]; // remove [0] if there could be more than one root nodes 
} 

echo json_encode(makeRecursive(array(
    array('id' => 5273, 'parent' => 0, 'name' => 'John Doe'), 
    array('id' => 6032, 'parent' => 5273, 'name' => 'Sally Smith'), 
    array('id' => 6034, 'parent' => 6032, 'name' => 'Mike Jones'), 
    array('id' => 6035, 'parent' => 6034, 'name' => 'Jason Williams'), 
    array('id' => 6036, 'parent' => 5273, 'name' => 'Sara Johnson'), 
    array('id' => 6037, 'parent' => 5273, 'name' => 'Dave Wilson'), 
    array('id' => 6038, 'parent' => 6037, 'name' => 'Amy Martin'), 
))); 

डेमो: https://3v4l.org/s2PNC

+0

योशी, धन्यवाद। मैंने परीक्षण के खिलाफ अपना कोड चलाया और यह बहुत अच्छा काम करता है। हालांकि जब मैंने कुछ असली दुनिया डेटा लागू किया तो 300-400 लोग हो सकते हैं। मुझे PHP PHP की 128 एमबी त्रुटि समाप्त हो गई है। मैं समझता हूं कि मैंने 300-400 रिकॉर्ड अधिक उदाहरण दिए हैं, लेकिन मुझे नहीं लगता था कि इसे एक बड़ा डेटा सेट माना जाएगा। कोई विचार? क्या यह समझ में आता है कि इस तरह की स्मृति का उपयोग किया? – maestrojed

+0

@maestrojed मेरे पहले संस्करण (शायद स्मृति रिसाव का कारण) में एक त्रुटि हुई थी, कृपया अद्यतन पर एक नज़र डालें। – Yoshi

+1

वह काम करता था और फिर मुझे उम्मीद थी। सहायता के लिए धन्यवाद। मैं इसका विश्लेषण करने और कुछ सीखने की आशा करता हूं! – maestrojed

2

कोड काम करेगा बाद में जोड़ने के लिए काम करने के लिए जा रहा था काम करने के लिए, तो मुझे मिल गया .. आप अपनी आवश्यकताओं के अनुसार थोड़ा tweak कर सकते हैं।

$data = array(
    '5273' => array('id' =>5273, 'name'=> 'John Doe', 'parent'=>''), 
    '6032' => array('id' =>6032, 'name'=> 'Sally Smith', 'parent'=>'5273'), 
    '6034' => array('id' =>6034, 'name'=> 'Mike Jones ', 'parent'=>'6032'), 
    '6035' => array('id' =>6035, 'name'=> 'Jason Williams', 'parent'=>'6034') 
    ); 

$fdata = array(); 


function ConvertToMulti($data) { 
    global $fdata; 

    foreach($data as $k => $v) 
    { 
     if(empty($v['parent'])){ 
      unset($v['parent']); 
     $v['data'] = array(); 
     $v['children'] = array(); 
      $fdata[] = $v; 
     } 
     else { 
      findParentAndInsert($v, $fdata); 
     } 

    } 
} 

function findParentAndInsert($idata, &$ldata) { 

    foreach ($ldata as $k=>$v) { 

     if($ldata[$k]['id'] == $idata['parent']) { 
      unset($idata['parent']); 
     $idata['data'] = array(); 
     $idata['children'] = array(); 
      $ldata[$k]['children'][] = $idata; 
      return; 
     } 
     else if(!empty($v['children'])) 
      findParentAndInsert($idata, $ldata[$k]['children']); 
    } 
} 


print_r($data); 
ConvertToMulti($data); 
echo "AFTER\n"; 
print_r($fdata); 

http://codepad.viper-7.com/Q5Buaz

+0

मैं सुबह में यह कोशिश करने जा रहा हूं। पहले कार्यान्वयन पर यह समस्याएं प्रतीत होती थीं। मुझे यकीन नहीं है कि अभी तक क्या है और विवरण के साथ टिप्पणी करने का प्रयास करेंगे। जब मैंने इसे कार्यान्वित किया तो मुझे कोई त्रुटि नहीं मिली और संरचना सही प्रतीत होती है लेकिन बहुत सारे डेटा गायब हैं। – maestrojed

+0

कृपया कुछ चीजें नोट करें, सबसे पहले, $ डेटा सरणी को अपने साथ भरें। आपके पास इस प्रश्न में उपयोग किए जाने वाले सभी मूल्य नहीं हैं। दूसरा, आप ConvertToMulti फ़ंक्शन में $ fdata स्थानीय बना सकते हैं। इसे वैश्विक बनाना आपके कार्यान्वयन में समस्या का कारण बन सकता है। आपके कार्यान्वयन के साथ शुभकामनाएं – FatalError

3

ठीक है, यह यह कैसे काम करता है, तो आप वास्तव में नहीं बहुत दूर दूर के रूप में आप शुरू कर दिया है, लेकिन क्या आप वास्तव में देखने के संदर्भ हैं कर रहे थे। यह एक सामान्य प्रक्रिया है:

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

// create an index on id 
$index = array(); 
foreach($rows as $row) 
{ 
    $row['data'] = (object) array(); 
    $index[$row['id']] = $row; 
} 

तो अब सभी प्रविष्टियों उनके आईडी पर सूचीबद्ध कर रहे हैं। यह पहला कदम था।

दूसरा चरण समान रूप से सीधे आगे है। क्योंकि अब हम $index में अपने आईडी के आधार पर प्रत्येक नोड तक पहुंच सकते हैं, हम बच्चों को अपने माता-पिता को असाइन कर सकते हैं।

एक "वर्चुअल" नोड है, जो आईडी 0 वाला है।यह किसी भी पंक्ति में मौजूद नहीं है, हालांकि, अगर हम इसमें बच्चों को भी जोड़ सकते हैं, तो हम आपके बच्चों के संग्रह को सभी रूट नोड्स के लिए स्टोर के रूप में उपयोग कर सकते हैं, आपके मामले में, एक रूट रूट नोड है।

निश्चित रूप से, आईडी 0 के लिए, हमें माता-पिता को संसाधित नहीं करना चाहिए - क्योंकि यह अस्तित्व में नहीं है।

तो चलिए ऐसा करते हैं। हम यहाँ संदर्भ का इस्तेमाल करते हैं क्योंकि अन्यथा एक ही नोड दोनों माता पिता और बच्चे नहीं हो सकता:

// build the tree 
foreach($index as $id => &$row) 
{ 
    if ($id === 0) continue; 
    $parent = $row['parent']; 
    $index[$parent]['children'][] = &$row; 
} 
unset($row); 

क्योंकि हम संदर्भ का उपयोग, अंतिम पंक्ति पाश के बाद $row में संग्रहीत संदर्भ अनसेट करने के लिए ख्याल रखता है।

अब सभी बच्चों को अपने माता-पिता को सौंपा गया है। यह पहले से ही हो सकता है, हालांकि अंतिम चरण को न भूलें, आउटपुट के लिए वास्तविक नोड को एक्सेस किया जाना चाहिए।

ब्रेवटी के लिए, रूट नोड को $index पर ही असाइन करें। अगर हम याद है, केवल रूट नोड हम चाहते हैं आईडी 0 साथ नोड में बच्चों सरणी में पहले से एक है:

// obtain root node 
$index = $index[0]['children'][0]; 

और बस हो गया। हम इसे अब उपयोग कर सकते हैं सीधे JSON उत्पन्न करने के लिए:

// output json 
header('Content-Type: application/json'); 
echo json_encode($index); 

अंत में एक नज़र में संपूर्ण कोड:

<?php 
/** 
* @link http://stackoverflow.com/questions/11239652/php-create-a-multidimensional-array-from-an-array-with-relational-data 
*/ 

$rows = array(
    array('id' => 5273, 'parent' => 0, 'name' => 'John Doe'), 
    array('id' => 6032, 'parent' => 5273, 'name' => 'Sally Smith'), 
    array('id' => 6034, 'parent' => 6032, 'name' => 'Mike Jones'), 
    array('id' => 6035, 'parent' => 6034, 'name' => 'Jason Williams'), 
    array('id' => 6036, 'parent' => 5273, 'name' => 'Sara Johnson'), 
    array('id' => 6037, 'parent' => 5273, 'name' => 'Dave Wilson'), 
    array('id' => 6038, 'parent' => 6037, 'name' => 'Amy Martin'), 
); 

// create an index on id 
$index = array(); 
foreach($rows as $row) 
{ 
    $row['data'] = (object) []; 
    $index[$row['id']] = $row; 
} 

// build the tree 
foreach($index as $id => &$row) 
{ 
    if ($id === 0) continue; 
    $parent = $row['parent']; 
    $index[$parent]['children'][] = &$row; 
} 
unset($row); 

// obtain root node 
$index = $index[0]['children'][0]; 

// output json 
header('Content-Type: application/json'); 
echo json_encode($index, JSON_PRETTY_PRINT); 

कौन सा (PHP 5.4s के साथ 'JSON_PRETTY_PRINT यहाँ) निम्नलिखित json बनाना होगा:

{ 
    "id": 5273, 
    "parent": 0, 
    "name": "John Doe", 
    "data": { 

    }, 
    "children": [ 
     { 
      "id": 6032, 
      "parent": 5273, 
      "name": "Sally Smith", 
      "data": { 

      }, 
      "children": [ 
       { 
        "id": 6034, 
        "parent": 6032, 
        "name": "Mike Jones", 
        "data": { 

        }, 
        "children": [ 
         { 
          "id": 6035, 
          "parent": 6034, 
          "name": "Jason Williams", 
          "data": { 

          } 
         } 
        ] 
       } 
      ] 
     }, 
     { 
      "id": 6036, 
      "parent": 5273, 
      "name": "Sara Johnson", 
      "data": { 

      } 
     }, 
     { 
      "id": 6037, 
      "parent": 5273, 
      "name": "Dave Wilson", 
      "data": { 

      }, 
      "children": [ 
       { 
        "id": 6038, 
        "parent": 6037, 
        "name": "Amy Martin", 
        "data": { 

        } 
       } 
      ] 
     } 
    ] 
} 
+0

क्या आप कृपया बता सकते हैं कि क्या अनसेट ($ पंक्ति); –

+0

@LovepreetSinghBatth कर रहा है: यह "क्योंकि हम संदर्भों का उपयोग करते हैं, अंतिम पंक्ति लूप के बाद $ पंक्ति में संग्रहीत संदर्भ को अनसेट करने का ख्याल रखती है।" उदाहरण के नीचे यह है। – hakre

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