PHP按ID和父ID排序数组

时间:2014-11-10 16:51:56

标签: php arrays sorting parentid

我搜索了很多这个问题:

我有一个阵列:

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 = 0 0级,此ID的每个孩子都有 1级等。

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

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

2 个答案:

答案 0 :(得分: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));

答案 1 :(得分:2)

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

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

该方法执行以下操作:

  • 迭代所有元素,直到flat数组为空(它假定每个元素都是根元素或在数组中有匹配的父元素)
  • 如果是根元素,请将其添加到result root
  • 如果匹配的父级已经转移到result数组,请将该元素添加为子级。

我使用了第二个数组$refs,它只包含基于其id的每个元素的引用,因为它允许在{em>任意级别的$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"];
}

当然可以使用相同的逻辑来操纵标题,显示数据等......