2

我搜索了很多这个问题:

我有一个数组:

array(
  array('id' = '1'; 'parent' = '0'; 'title' = 'XXX1');
  array('id' = '85'; 'parent' = '0'; 'title' = 'XXX2');
  array('id' = '41'; 'parent' = '0'; 'title' = 'XXX2');
  array('id' = '17'; 'parent' = '0'; 'title' = 'XXX3');
  array('id' = '66'; 'parent' = '1'; 'title' = 'XXX4');
  array('id' = '92'; 'parent' = '1'; 'title' = 'XXX5');
  array('id' = '65'; 'parent' = '1'; 'title' = 'XXX6');
  array('id' = '45'; 'parent' = '41'; 'title' = 'XXX7');
  array('id' = '19'; 'parent' = '92'; 'title' = 'XXX8');
  array('id' = '101'; 'parent' = '45'; 'title' = 'XXX9');
  array('id' = '102'; 'parent' = '45'; 'title' = 'XXX10');
  array('id' = '103'; 'parent' = '19'; 'title' = 'XXX11');
  array('id' = '104'; 'parent' = '19'; 'title' = 'XXX12');
  array('id' = '105'; 'parent' = '19'; 'title' = 'XXX13');
);

我怎样才能对其进行排序:

  • 它按 ID 排序if parent == 0,但如果它有孩子,他们应该紧跟在他们的父母之后。如果那个孩子有孩子,他们也应该在其父母之后。

  • 考虑项目where parent = 00 级,这个 id 的每个孩子都有1 级等。

  • 现在:If level = 0它应该在标题前添加“-TITLE”。如果级别为 2 - "--TITLE",如果级别为 5 - "-----TITLE"

我有大约 300 条记录,最高级别约为 4。我不需要级别 < 5 的排序脚本,但也需要级别 100。

4

2 回答 2

3

当您使用 hira ...heira... 树状数据时,将数据表示为树总是一个好主意。

以下片段可用于将您的平面数组转换为一棵树,您现在可以通过递归处理children给定元素的所有数组来轻松处理它。

该方法执行以下操作:

  • 遍历所有元素,直到平面数组为空(它假定每个元素都是根元素或在数组中具有匹配的父元素)
  • 如果它是根元素,则将其添加到result
  • 如果匹配的父元素已经转移到result数组中,则将该元素添加为子元素。

我使用了第二个数组$refs,它仅包含基于每个元素的 id 的引用,因为它允许在数组的任何级别插入元素,$result 而无需搜索正确的级别。

ps.:可能有更容易理解的递归方法。

pps.:我向任何元素添加了一个空的子数组,因此在插入子元素时我不必处理不存在的数组。

<?php
$arr = array(
  array('id' => 1, 'parent' => 0, 'title' => 'XXX1', 'children'=>array()),
  array('id' => 85, 'parent' => 0, 'title' => 'XXX2', 'children'=>array()),
  array('id' => 41, 'parent' => 0, 'title' => 'XXX2', 'children'=>array()),
  array('id' => 17, 'parent' => 0, 'title' => 'XXX3', 'children'=>array()),
  array('id' => 66, 'parent' => 1, 'title' => 'XXX4', 'children'=>array()),
  array('id' => 92, 'parent' => 1, 'title' => 'XXX5', 'children'=>array()),
  array('id' => 65, 'parent' => 1, 'title' => 'XXX6', 'children'=>array()),
  array('id' => 45, 'parent' => 41, 'title' => 'XXX7', 'children'=>array()),
  array('id' => 19, 'parent' => 92, 'title' => 'XXX8', 'children'=>array()),
  array('id' => 101, 'parent' => 45, 'title' => 'XXX9', 'children'=>array()),
  array('id' => 102, 'parent' => 45, 'title' => 'XXX10', 'children'=>array()),
  array('id' => 103, 'parent' => 19, 'title' => 'XXX11', 'children'=>array()),
  array('id' => 104, 'parent' => 19, 'title' => 'XXX12', 'children'=>array()),
  array('id' => 105, 'parent' => 19, 'title' => 'XXX13', 'children'=>array())
);

$newArr = unflattenArray($arr);

echo "<pre>";
print_r($newArr);
echo "</pre>";


function unflattenArray($flatArray){
  $refs = array(); //for setting children without having to search the parents in the result tree.
    $result = array();

    //process all elements until nohting could be resolved.
    //then add remaining elements to the root one by one. 
    while(count($flatArray) > 0){
        for ($i=count($flatArray)-1; $i>=0; $i--){
            if ($flatArray[$i]["parent"]==0){
                //root element: set in result and ref!
                $result[$flatArray[$i]["id"]] = $flatArray[$i]; 
                $refs[$flatArray[$i]["id"]] = &$result[$flatArray[$i]["id"]];
                unset($flatArray[$i]);
        $flatArray = array_values($flatArray);
            }

            else if ($flatArray[$i]["parent"] != 0){
                //no root element. Push to the referenced parent, and add to references as well. 
                if (array_key_exists($flatArray[$i]["parent"], $refs)){
                    //parent found
                    $o = $flatArray[$i];
                    $refs[$flatArray[$i]["id"]] = $o;
          $refs[$flatArray[$i]["parent"]]["children"][] = &$refs[$flatArray[$i]["id"]];
                    unset($flatArray[$i]);
          $flatArray = array_values($flatArray);
                }
            }
        }
  }
  return $result;
}

这个方法会返回一个类似(outtake)的结果:

[1] => Array
        (
            [id] => 1
            [parent] => 0
            [title] => XXX1
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 65
                            [parent] => 1
                            [title] => XXX6
                            [children] => Array
                                (
                                )

                        )

                    [1] => Array
                        (
                            [id] => 92
                            [parent] => 1
                            [title] => XXX5
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 19
                                            [parent] => 92

仍然是未排序的,但现在是可以轻松处理的格式。

例如要对所有内容进行排序,您现在可以简单地使用递归排序方法,例如

sortMyArrays($newArr);
echo "<pre>";
print_r($newArr);
echo "</pre>";

function sortMyArrays(&$arr){
   uasort($arr, "srt");
   foreach ($arr as $a) {
     sortMyArrays($a["children"]);
   }
}

function srt($a, $b){
  return $a["id"] - $b["id"];
}

当然,同样的逻辑也可以用来操作标题、显示数据等……

于 2014-11-10T18:50:53.030 回答
2

你的问题是你有一个一维数组试图做一些实际上是要显示在树中的事情。这意味着当您的孩子链接到父母时,该父母应该知道它的孩子是谁,但在这种情况下他们不知道。因此,您可以将其放入一个新的数据结构中,或者构建一个递归函数来计算每个的父级。

这是通过首先按全局 ID 排序来完成的。这将确保我们不需要进行任何其他排序,因为数组已经按照您想要的顺序(在每个级别)。然后我们简单地依次获取每个级别,递归地查找该级别的项目并将它们附加到列表中:

<?php

$dudzio = array(
  array('id' => 1, 'parent' => 0, 'title' => 'XXX1'),
  array('id' => 85, 'parent' => 0, 'title' => 'XXX2'),
  array('id' => 41, 'parent' => 0, 'title' => 'XXX2'),
  array('id' => 17, 'parent' => 0, 'title' => 'XXX3'),
  array('id' => 66, 'parent' => 1, 'title' => 'XXX4'),
  array('id' => 92, 'parent' => 1, 'title' => 'XXX5'),
  array('id' => 65, 'parent' => 1, 'title' => 'XXX6'),
  array('id' => 45, 'parent' => 41, 'title' => 'XXX7'),
  array('id' => 19, 'parent' => 92, 'title' => 'XXX8'),
  array('id' => 101, 'parent' => 45, 'title' => 'XXX9'),
  array('id' => 102, 'parent' => 45, 'title' => 'XXX10'),
  array('id' => 103, 'parent' => 19, 'title' => 'XXX11'),
  array('id' => 104, 'parent' => 19, 'title' => 'XXX12'),
  array('id' => 105, 'parent' => 19, 'title' => 'XXX13')
);

function sortDudzio($a, $b)
{
    // If you need to switch which way the values are sorted
    // switch the 1 and -1 around
    if($a['id'] > $b['id']) {
        return 1;
    } elseif($a['id'] < $b['id']) {
        return -1;
    } else {
        return 0;
    }
}

function getByParent($array, $id, $level)
{

    $orderedArray = array();

    foreach($array as $k=>$arr) {
        if($arr['parent'] == $id) {
            $arr['title'] = str_repeat('-', $level) . $arr['title'];
            $orderedArray[] = $arr;
            $children = getByParent($array, $arr['id'], $level + 1);
            foreach($children as $child) {
                $orderedArray[] = $child;
            }
        }
    }

    return $orderedArray;

}

usort($dudzio, 'sortDudzio');

print_r(getByParent($dudzio, 0, 0));
于 2014-11-10T17:51:53.627 回答