2016-12-12 21 views
3

我試圖建立從數據庫查詢的結果陣列和basicly我在想,如果下面有可能排序多維數組在PHP中使用多個條件語句

陣列內容:

Array 
(
    [0] => Array 
     (
      [Section_Id] => 1 
      [Section_Name] => "Section1" 
      [Section_Parent] => NULL 
      [Section_Position] => 0 
      [Section_Depth] => 0 
     ) 

    [1] => Array 
     (
      [Section_Id] => 3 
      [Section_Name] => "Section2" 
      [Section_Parent] => NULL 
      [Section_Position] => 1 
      [Section_Depth] => 0 

     ) 

    [2] => Array 
     (
      [Section_Id] => 4 
      [Section_Name] => "SubSection1ForSection2" 
      [Section_Parent] => 3 
      [Section_Position] => 0 
      [Section_Depth] => 1 
     ) 

    [3] => Array 
     (
      [Section_Id] => 2 
      [Section_Name] => "SubSection1ForSection1" 
      [Section_Parent] => 1 
      [Section_Position] => 0 
      [Section_Depth] => 1 
     ) 

) 

如果你想解決這一個讓說上Section_Position它會返回類似:

usort($sections, function($a, $b) { 
    return $a['section_position'] - $b['section_position']; 
}); 
  1. SECTION1
  2. SubSection1ForSection2
  3. SubSection1ForSection1
  4. 第2節

雖然我需要與他們各自的孩子的訂購章節:

  1. SECTION1
  2. SubSection1ForSection1
  3. 第2節
  4. 個SubSection1ForSection2

我認爲Somehow Duplicate Question是思考的方式,但我似乎無法找到一種方法,使這項工作對我來說。

有沒有辦法做到這一點,或者我必須與forloop-gets做一個解決方法,以便我首先獲得深度的所有值,然後使用該部分的名稱來獲取深度的所有值二等等?

(對不起,我的英語。)

+0

[按值排序多維數組](http:// stackoverflow。com/questions/2699086/sort-multi-dimensional-array-by-value) –

+0

不完全重複...我只是單純地說可能重複的答案不夠... :)我需要一些更多的排序,如考慮到父母 – Akorna

+0

只是一個建議:也請檢查http://stackoverflow.com/questions/17364127/how-can-i-sort-arrays-and-data-in-php(由前面的Q.鏈接)那裏有很多答案,其中一些有10多種不同類型的多維數組排序算法。如果沒有現成的答案,請嘗試結合一些想法。 –

回答

1

好吧,這可能是一個醜陋的解決方案,但如果你把一切都放在一個功能它看起來不錯:)。好的是,它會在你的情況下工作。

代碼:

$inputData = array(
    array(
     'Section_Id' => 1, 
     'Section_Name' => "Section1", 
     'Section_Parent' => NULL, 
     'Section_Position' => 1, 
     'Section_Depth' => 0, 
    ), 
    array(
     'Section_Id' => 2, 
     'Section_Name' => "Section2", 
     'Section_Parent' => NULL, 
     'Section_Position' => 0, 
     'Section_Depth' => 0 
    ), 
    array(
     'Section_Id' => 4, 
     'Section_Name' => "SubSection2ForSection2", 
     'Section_Parent' => 2, 
     'Section_Position' => 1, 
     'Section_Depth' => 1 
    ), 
    array(
     'Section_Id' => 5, 
     'Section_Name' => "SubSection1ForSection2", 
     'Section_Parent' => 2, 
     'Section_Position' => 0, 
     'Section_Depth' => 1 
    ), 
    array(
     'Section_Id' => 3, 
     'Section_Name' => "SubSection1ForSection1", 
     'Section_Parent' => 1, 
     'Section_Position' => 0, 
     'Section_Depth' => 1 
    ) 
); 


$parentRecords = array(); 
$childRecords = array(); 
$sorted = array(); 

/* split in two collections */ 
foreach ($inputData as $sectionData) { 
    if (is_null($sectionData['Section_Parent'])) { 
     /* assume this is a parent */ 
     $parentRecords[] = $sectionData; 
    } else { 
     /* assume we are on child row */ 
     $childRecords[] = $sectionData; 
    } 
} 

/* now first order parents by Section_Position */ 
usort($parentRecords, function($a, $b) { 

     if ($a['Section_Position'] == $b['Section_Position']) { 
      return 0; 
     } 
     return $a['Section_Position'] > $b['Section_Position'] ? 1 : -1; 
    }); 

/* now the actual sorting */ 
foreach ($parentRecords as $parentData) { 
    $parentId = $parentData['Section_Id']; 
    /* now get all children of this parent */ 
    $parentChildren = array(); 
    foreach ($childRecords as $childData) { 
     if ($childData['Section_Parent'] == $parentId) { 
      $parentChildren[] = $childData; 
     } 
    } 

    /* now sort the children by Section_Position */ 
    usort($parentChildren, function($a, $b) { 

     if ($a['Section_Position'] == $b['Section_Position']) { 
      return 0; 
     } 
     return $a['Section_Position'] > $b['Section_Position'] ? 1 : -1; 
    }); 

    $sorted[] = $parentData; 
    $sorted = array_merge($sorted, $parentChildren); 
} 


echo '<pre>' . print_r($sorted, true) . '</pre>'; 
exit; 

OUTPUT:

Array 
(
    [0] => Array 
     (
      [Section_Id] => 2 
      [Section_Name] => Section2 
      [Section_Parent] => 
      [Section_Position] => 0 
      [Section_Depth] => 0 
     ) 

    [1] => Array 
     (
      [Section_Id] => 5 
      [Section_Name] => SubSection1ForSection2 
      [Section_Parent] => 2 
      [Section_Position] => 0 
      [Section_Depth] => 1 
     ) 

    [2] => Array 
     (
      [Section_Id] => 4 
      [Section_Name] => SubSection2ForSection2 
      [Section_Parent] => 2 
      [Section_Position] => 1 
      [Section_Depth] => 1 
     ) 

    [3] => Array 
     (
      [Section_Id] => 1 
      [Section_Name] => Section1 
      [Section_Parent] => 
      [Section_Position] => 1 
      [Section_Depth] => 0 
     ) 

    [4] => Array 
     (
      [Section_Id] => 3 
      [Section_Name] => SubSection1ForSection1 
      [Section_Parent] => 1 
      [Section_Position] => 0 
      [Section_Depth] => 1 
     ) 

) 

注:第一個排序是對於父母做Section_Position,然後對孩子的Section_Position

P u,d一個T E

首先,我想向版主抱歉,我們與@Akorna進行了長時間的討論,但我需要向他提供此代碼,我認爲它將爲未來做好工作。所以@Akorna應該爲你工作的代碼是這一個:

$inputData = array(
    array(
     'section_id' => 333, 
     'section_depth' => 1, 
     'section_parent' => 332, 
     'section_position' => 0, 
     'section_title' => 'Introduction'), 
    array(
     'section_id' => 334, 
     'section_depth' => 1, 
     'section_parent' => 332, 
     'section_position' => 1, 
     'section_title' => 'Glossary'), 
    array(
     'section_id' => 335, 
     'section_depth' => 1, 
     'section_parent' => 332, 
     'section_position' => 2, 
     'section_title' => 'Commands'), 
    array(
     'section_id' => 336, 
     'section_depth' => 1, 
     'section_parent' => 332, 
     'section_position' => 3, 
     'section_title' => 'Components'), 
    array(
     'section_id' => 337, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 0, 
     'section_title' => 'Introduction'), 
    array(
     'section_id' => 407, 
     'section_depth' => 2, 
     'section_parent' => 401, 
     'section_position' => 2, 
     'section_title' => 'Web Application'), 
    array(
     'section_id' => 338, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 1, 
     'section_title' => 'AbstractContainer'), 
    array(
     'section_id' => 406, 
     'section_depth' => 2, 
     'section_parent' => 401, 
     'section_position' => 1, 
     'section_title' => 'Web Application'), 
    array(
     'section_id' => 339, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 2, 
     'section_title' => 'ActionsContainer'), 
    array(
     'section_id' => 340, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 3, 
     'section_title' => 'BrowserIncompatibility'), 
    array(
     'section_id' => 404, 
     'section_depth' => 2, 
     'section_parent' => 402, 
     'section_position' => 3, 
     'section_title' => 'Web Application'), 
    array(
     'section_id' => 341, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 4, 
     'section_title' => 'CollapsibleContainer'), 
    array(
     'section_id' => 342, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 5, 
     'section_title' => 'DetailsContainer'), 
    array(
     'section_id' => 343, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 6, 
     'section_title' => 'DynamicMenu'), 
    array(
     'section_id' => 403, 
     'section_depth' => 2, 
     'section_parent' => 402, 
     'section_position' => 1, 
     'section_title' => 'Web Application'), 
    array(
     'section_id' => 344, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 7, 
     'section_title' => 'Settings'), 
    array(
     'section_id' => 345, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 8, 
     'section_title' => 'SubfilesViewer'), 
    array(
     'section_id' => 346, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 9, 
     'section_title' => 'Taxonomy Management'), 
    array(
     'section_id' => 402, 
     'section_depth' => 1, 
     'section_parent' => 400, 
     'section_position' => 2, 
     'section_title' => 'Web Application'), 
    array(
     'section_id' => 401, 
     'section_depth' => 1, 
     'section_parent' => 400, 
     'section_position' => 1, 
     'section_title' => 'Web Application'), 
    array(
     'section_id' => 347, 
     'section_depth' => 2, 
     'section_parent' => 336, 
     'section_position' => 10, 
     'section_title' => 'UploadQueue'), 
    array(
     'section_id' => 400, 
     'section_depth' => 0, 
     'section_parent' => null, 
     'section_position' => 5, 
     'section_title' => 'Web Application'), 
    array(
     'section_id' => 332, 
     'section_depth' => 0, 
     'section_parent' => null, 
     'section_position' => 3, 
     'section_title' => 'Web Application') 
); 

/* first order by section_depth and then by section_position */ 
$inputData = array_orderby($inputData, 'section_depth', SORT_ASC, 'section_position', SORT_ASC); 

$parents = array(); 
$sortedByParent = false; 
while (!$sortedByParent) { 
    $elems = array_splice($inputData, count($inputData) - 1, 1); 
    if (!count($elems)) { 
     $sortedByParent = true; 
     $inputData = array_merge($inputData, $parents); 
     continue; 
    } 

    $elem = $elems[0]; 

    if ($elem['section_depth'] == 0) { 
     if (!isset($elem['children'])) { 
      $elem['children'] = array(); 
     } 
     $parents[] = $elem; 
    } else { 
     $inputData = put_in_parent($elem, $inputData); 
    } 
} 

/* now we have $inputData in nice format like 
* parent(child, child, child(child, child(child, child)), child(child(child(child)))), 
* parent(child, child, child(child, child(child, child)), child(child(child(child)))) 
* */ 
$inputData = merge_children_recursively(array_reverse($inputData)); 

function merge_children_recursively($inputData) { 
    $children = array(); 
    foreach ($inputData as $row) { 
     if (isset($row['children'])) { 
      /* this ksort call is necessary because the key is actually section_position */ 
      ksort($row['children']); 
      $rowCopy = $row; 
      unset($rowCopy['children']); 
      $children[] = $rowCopy; 
      $children = array_merge($children, merge_children_recursively($row['children'])); 
     } else { 
      $children[] = $row; 
     } 
    } 

    return $children; 
} 

function put_in_parent($elem, $inputData) { 
    foreach ($inputData as $k => $row) { 
     if ($row['section_id'] == $elem['section_parent']) { 
      if (!isset($inputData[$k]['children'])) { 
       $inputData[$k]['children'] = array(); 
      } 

      $inputData[$k]['children'][$elem['section_position']] = $elem; 
      break; 
     } 
    } 
    return $inputData; 
} 

function array_orderby() { 
    $args = func_get_args(); 
    $data = array_shift($args); 
    foreach ($args as $n => $field) { 
     if (is_string($field)) { 
      $tmp = array(); 
      foreach ($data as $key => $row) { 
       $tmp[$key] = $row[$field]; 
      } 
      $args[$n] = $tmp; 
     } 
    } 
    $args[] = &$data; 
    call_user_func_array('array_multisort', $args); 
    return array_pop($args); 
} 

echo '<pre>' . print_r($inputData, true) . '</pre>'; 
exit; 

我的確從輸入數據刪除一些東西,所以我能確定自己的方向。只要嘗試將輸入數據提供給邏輯並讓我知道結果如何。

+0

@Akorna,但我真的建議你避免這樣的事情,並更好地考慮使用'ORDER BY'排序數據與SQL查詢。 – codtex

+0

你給的例子不適合我,因爲我這樣做的全部原因是因爲這些部分實際上可以從訂單/深度(因此部分位置和父/子關係)發生改變。該代碼的限制方式是,如果您說第一個項目突然排在最後一行,它仍然會將子項置於第一行。當訂購的位置,而不是後續身份證,父母將不見了,但孩子不會跟着等 我想用Order By來做,但我不能讓孩子關係像我想要的那樣級別和我對數據庫的訪問是有限的。 :/ – Akorna

+0

http://pastebin.com/xrfnC0hT這是我從使用你的零件得到的結果,但是適用於使用section_Position而不是更新後不代表結構的Section_Id。正如你將要注意到的那樣,Folder-Childs不在它們各自的父母之下:( – Akorna