2012-09-05 31 views
5

मैं श्रेणियों में से एक समूह के साथ एक डेटाबेस है बनाना, कुछ बच्चे हैं:एक पुनरावर्ती श्रेणी पेड़ समारोह

Array 
(
    [0] => Array 
     (
      [id] => 1 
      [name] => Home Improvement 
      [slug] => Home-Improvement 
      [parent] => 
      [user_id] => 1 
      [order] => 1 
     ) 

    [1] => Array 
     (
      [id] => 2 
      [name] => Asbestos Abatement & Removal 
      [slug] => Asbestos-Abatement-Removal 
      [parent] => 1 
      [user_id] => 1 
      [order] => 8 
     ) 

    [2] => Array 
     (
      [id] => 3 
      [name] => Asphalt & Asphalt Products 
      [slug] => Asphalt-Asphalt-Products 
      [parent] => 1 
      [user_id] => 1 
      [order] => 9 
     ) 

    [3] => Array 
     (
      [id] => 4 
      [name] => Bathroom 
      [slug] => Bathroom 
      [parent] => 1 
      [user_id] => 1 
      [order] => 10 
     ) 

    [4] => Array 
     (
      [id] => 5 
      [name] => Kitchen Cabinets 
      [slug] => Kitchen-Cabinets 
      [parent] => 1 
      [user_id] => 1 
      [order] => 11 
     ) 

    [5] => Array 
     (
      [id] => 6 
      [name] => Ceilings 
      [slug] => Ceilings 
      [parent] => 1 
      [user_id] => 1 
      [order] => 12 
     ) 

    [6] => Array 
     (
      [id] => 7 
      [name] => Cleaning 
      [slug] => Cleaning 
      [parent] => 1 
      [user_id] => 1 
      [order] => 13 
     ) 

    [7] => Array 
     (
      [id] => 8 
      [name] => Closet Organizers & Accessories 
      [slug] => Closet-Organizers-Accessories 
      [parent] => 1 
      [user_id] => 1 
      [order] => 14 
     ) 

    [8] => Array 
     (
      [id] => 9 
      [name] => Concrete 
      [slug] => Concrete 
      [parent] => 1 
      [user_id] => 1 
      [order] => 15 
     ) 

    [9] => Array 
     (
      [id] => 10 
      [name] => Contractors & Service Providers 
      [slug] => Contractors-Service-Providers 
      [parent] => 1 
      [user_id] => 1 
      [order] => 16 
     ) 

क्या मैं उत्पादन के लिए कोशिश कर रहा हूँ कुछ इस तरह है:

<ul> 
    <li>Parent 
     <ul> 
      <li>Child</li> 
     </ul> 
    </li> 
    <li>Parent with no Children</li> 
</ul> 

मैं मैं PHP में एक रिकर्सिव पेड़ स्क्रिप्ट बनाने की कोशिश कर रहा हूं, लेकिन मैं अटक गया हूं। यहां तक ​​कि मेरे पास अभी तक क्या है। मैं अटक गया हूं कि दूसरे के बीच क्या करना है: और endif; foreach में। (और मैं यहां आसानी से पढ़ने के लिए उस वाक्यविन्यास का उपयोग कर रहा हूं।) कोई सुझाव?

echo $this->categories->makeTree(0, $this->db->get('categories')->result_array()); 

public static function makeTree($parent, $array) 
{ 
    if (!is_array($array)) return ''; 

    $output = '<ul>'; 

    foreach($array as $key => $value): 
    if ($value['parent'] == $parent): 
     $output .= '<li>'; 

     if ($value['parent'] == NULL): 
      $output .= $value['name']; 
     else: 

     endif; 
    endif; 

    $output .= '</li>'; 
    endforeach; 

    $output .= '</ul>'; 
    return $output; 
} 

संपादित करें 1

मैं इस काम के प्राप्त करने में सक्षम था, हालांकि मैं एक foreach पाश, जो शायद सबसे अच्छा विचार नहीं है में एक डेटाबेस फोन है:

public function makeTree($parent, $array) 
{ 
    if (!is_array($array)) return FALSE; 

    $output = '<ul>'; 

    foreach($array as $key => $value): 
    if ($value['parent'] == $parent): 
     $output .= '<li>'; 

     if ($value['parent'] == NULL): 
      $output .= $value['name']; 

      $subcategories = ci()->db->get_where('categories', array('parent' => $value['id'])); 

      if ($subcategories->num_rows() > 0): 
       $output .= $this->makeTree($value['id'], $subcategories->result_array()); 
      endif; 
     else: 
      $output .= $value['name']; 
      $output .= '</li>'; 
     endif; 
    endif; 

    endforeach; 

    $output .= '</ul>'; 
    return $output; 
} 

संपादित करें 2

मेरा अंतिम समाधान है, डीबी qu करने के बजाय सरणी का पुन: उपयोग करना ery:

public function makeTree($parent, $array) 
{ 
    if (!is_array($array) OR empty($array)) return FALSE; 

    $output = '<ul>'; 

    foreach($array as $key => $value): 
    if ($value['parent'] == $parent): 
     $output .= '<li>'; 

     if ($value['parent'] == NULL): 
      $output .= $value['name']; 

      $matches = array(); 

      foreach($array as $subkey => $subvalue): 
       if ($subvalue['parent'] == $value['id']): 
        $matches[$subkey] = $subvalue; 
       endif; 
      endforeach; 

      $output .= $this->makeTree($value['id'], $matches); 

     else: 
      $output .= $value['name']; 
      $output .= '</li>'; 
     endif; 
    endif; 

    endforeach; 

    $output .= '</ul>'; 

    return $output; 
} 
+0

वर्तमान में यह 2 स्तरों की दूरी पर है। क्या हम इसे एन स्तर तक ले जा सकते हैं? –

उत्तर

7

हालांकि ऐसा लगता है, here देखें। दिखाए गए फ़ंक्शन के साथ आप अपने फ्लैट डेटा को केवल एक पुनरावृत्ति के साथ नेस्टेड डेटा में परिवर्तित कर सकते हैं। उस नेस्टेड डेटा से एक उल-सूची बनाना बहुत आसान है। उदाहरण के लिए:

function nested2ul($data) { 
    $result = array(); 

    if (sizeof($data) > 0) { 
    $result[] = '<ul>'; 
    foreach ($data as $entry) { 
     $result[] = sprintf(
     '<li>%s %s</li>', 
     $entry['name'], 
     nested2ul($entry['children']) 
    ); 
    } 
    $result[] = '</ul>'; 
    } 

    return implode($result); 
} 

echo nested2ul(array(flat2nested($yourFlatData)); 

इस दृष्टिकोण के बारे में अच्छी बात यह है कि आप बार-बार फिर से पुनरावृति करने के लिए इनपुट डेटा पर सिर्फ बच्चों के तत्वों को खोजने के लिए की जरूरत नहीं है कि है।

+0

मुझे यह पसंद है, लेकिन मुझे 'वापसी $ m [$ r] [0] पर "अपरिभाषित ऑफसेट: 0" मिल रहा है; 'बनाने में कामकाजी समारोह।वह फ़ंक्शन 'सरणी (सरणी' 'आईडी' => 5273, 'पैरेंट' => 0) जैसे डेटा की अपेक्षा कर रहा है) 'जबकि मेरी सरणी' ऐरे ([0] => ऐरे ([id] => 1, [पैरेंट ] => 0)) '। इस पर कोई सुझाव है कि मैं इसे कैसे ठीक कर सकता हूं? – dallen

+0

@ आपके द्वारा पोस्ट किए गए दो स्निपेट वास्तव में वही हैं। मुझे लगता है कि समस्या यह है कि आपका मूल अभिभावक मान एक खाली स्ट्रिंग है। जबकि सहायक कार्य '0' का उपयोग करता है ('$ r' पैरामीटर देखें)। सरणी कुंजी के रूप में एक खाली स्ट्रिंग थोड़ा समस्याग्रस्त है, इसलिए यदि आप इसे अपने इनपुट डेटा में बदल सकते हैं, तो मुझे लगता है कि बाकी को काम करना चाहिए। – Yoshi

0

इस प्रयास करें:

$cats = $this->db->get('categories')->result_array(); 

echo $this->categories->makeTree(0, $cats); 

public static function makeTree($parent, $array) 
{ 
    if (!is_array($array)) return ''; 

    $output = '<ul>'; 

    foreach($array as $key => $value): 
    if ($value['parent'] == $parent): 
     $output .= '<li>'; 

     if ($value['parent'] == NULL): 
      $output .= $value['name']; 
     else: 

     endif; 
    endif; 

    $output .= '</li>'; 

    $output .= $this->categories->makeTree($value['parent'], $cats); 

    endforeach; 

    $output .= '</ul>'; 
    return $output; 
} 
+0

काम नहीं करता है। मुझे बस एक 500 त्रुटि के साथ भ्रष्ट पृष्ठ मिलता है। – dallen

1

मैं कुछ इस तरह का उपयोग आमतौर पर, कृपया ध्यान दें

1 कोड के इस टुकड़े mysql_ *

आप 2 पदावनत उपयोग कर रही है स्तर का नाम वाला एक डेटाबेस फ़ील्ड होना चाहिए, यदि नल यह मुख्य श्रेणी है, यदि उसके पास कोई संख्या है, तो यह उस श्रेणी के उपश्रेणी है जिसमें n आईडी

function getFamilies($level = 0) { 
    $level++; 
    $sql = "SELECT id from families WHERE level IS NULL"; 
    if (mysql_num_rows($result) > 0) { 
     echo "<ul>"; 
      while($row = mysql_fetch_assoc($result)) { 
       echo "<li>".$row['id']; 
        getSubFamilies($level, $row['id']); 
       echo "</li>"; 
      } 
     echo "</ul>"; 
    } 
} 

function getSubFamilies($level, $id) { 
    $level++; 
    $sqlSubFamilies = "SELECT id FROM families WHERE level = ".$id.""; 
    $resultSubFamilies = mysql_query($sqlSubFamilies); 
    if (mysql_num_rows($resultSubFamilies) > 0) { 
     echo = "<ul>"; 
      while($rowSubFamilies = mysql_fetch_assoc($resultSubFamilies)) { 
       echo "<li>".$rowSubFamilies['id']; 
        getSubFamilies($level, $rowSubFamilies['id']); 
       echo "</li>"; 
      } 
     echo "</ul>"; 
    } 
} 

getFamilies($level = 0); 
+0

आपके मामले में, स्तर माता-पिता है, इसलिए "आईडी का चयन करें, श्रेणियों से नाम जहां माता-पिता शून्य है" – Pluda

2

मेरा अंतिम समाधान है, डीबी क्वेरी करने के बजाय सरणी का पुन: उपयोग करना। यदि आपके पास बेहतर समाधान है, तो कृपया पोस्ट करें!

public function makeTree($parent, $array) 
{ 
    if (!is_array($array) OR empty($array)) return FALSE; 

    $output = '<ul>'; 

    foreach($array as $key => $value): 
    if ($value['parent'] == $parent): 
     $output .= '<li>'; 

     if ($value['parent'] == NULL): 
      $output .= $value['name']; 

      $matches = array(); 

      foreach($array as $subkey => $subvalue): 
       if ($subvalue['parent'] == $value['id']): 
        $matches[$subkey] = $subvalue; 
       endif; 
      endforeach; 

      $output .= $this->makeTree($value['id'], $matches); 

     else: 
      $output .= $value['name']; 
      $output .= '</li>'; 
     endif; 
    endif; 

    endforeach; 

    $output .= '</ul>'; 

    return $output; 
} 
0

मुझे लगता है कि का उपयोग कर यह विधि अज्ञात फ़ंक्शन बहुत आसान है।

//--------------------------- PRINT NESTED CATEGORIES 
$cats_childs = array(); 

$q = $db->query("SELECT id, parent, name FROM categories"); 

while ($r = $db->row($q)) 
{ 
    $cats_childs[$r['parent']][$r['id']] = $r; 
} 

$nested2ul = function($data) use (&$nested2ul, &$cats_childs) { 
    if (!empty($data)) { 
     echo '<ul>'; 
     foreach ($data as $r) { 
      echo '<li>'; 
      echo $r['name']; 
      $flat2ul($cats_childs[$r['id']]); 
      echo '</li>'; 
     } 
     echo '</ul>'; 
    } 
}; 

echo $nested2ul($cats_childs[0]);