0

我有以下数组结构:

   |  ID  |  CategoryName  | ParentID 
    _________________________________
       1  |  Movies        | -1
    _________________________________
       2  |  Series        | -1
    _________________________________
       3  |  ActionMovies  |  1
    _________________________________
       4  |  HorrorMovies  |  1
    _________________________________
       5  |  ComedySeries  |  2
    _________________________________
       6  |  TVShows       | -1

我的目标是达到以下结构

目标:

   |  ID  |  CategoryName  | ParentID 
    _________________________________
       1  |  Movies        | -1
    _________________________________
       3  |  ActionMovies  |  1
    _________________________________
       4  |  HorrorMovies  |  1
    _________________________________
       2  |  Series        | -1
    _________________________________
       5  |  ComedySeries  |  2
    _________________________________
       6  |  TVShows       | -1

或用文字解释:

  • 父类别有ParentID = -1(示例电影)
  • 所有类别均保留其原始 ID 号
  • 应直接列在其 ParentCategory 之后(示例 ActionMovies)
  • RootCategories without Children,列在数组的末尾。(例如电视节目)

我怎样才能用 PHP 做到最好?我无权访问原始的 Mysql 查询,所以这不是一个选项:)

我已经开始使用此代码,但我不确定它是正确的路径,并且只需最少的努力/可读性

        $tmpList = Categories_Models_Main::getAllCategories();



    $categoryData = array();
    foreach ($tmpList as $index => $categoryObject) {
        $categoryData[] = array('id' => $categoryObject->id,
                                 'CategoryName' => $categoryObject->parentId,
                                 'name' => $categoryObject->name);


    }

    ///let us assume $categoryData is original state.

    ///Beginning of manipulation and re-sorting of $tmpList


    foreach ($categoryData as $key => $value) {

        $mainId[$key] = $value['id'];

        $parentId[$key] = $value['parentId'];

    }

    array_multisort($parentId, $mainId, $categoryData);
4

4 回答 4

1

将主数组一分为二,一个是那些没有子节点的节点,另一个是其余的项目。

使用 array_multisort 函数对项目数组进行排序,并使用您想要的标准对没有子项的类别数组进行排序。最后一步是将没有子元素的数组推送到另一个数组。

这种形式不是最有效的,但有第一种方法是有效的,在此之后,您可以节省时间优化代码。

于 2012-05-23T10:09:03.100 回答
1
$input = array(
    array("foo", "bar", "5"),
    array("barr", "baz", "9"),
    array("nyan", "nyu", "2")
);

usort($input, function($a, $b) {
    if($a[2] < $b[2]) {
        return -1;
    } else if($a[2] > $b[2]) {
        return 1;
    } else {
        return 0;
    }
});

var_dump($input);

你的意思是这样的吗?这个想法是使用您知道的条件手动比较数组的内容。由于要排序的东西是唯一的,因此必须始终实现如何排序的逻辑。使用 PHP,PHP 的排序功能大部分时间都能正确执行。

于 2012-05-23T10:11:23.923 回答
1

我很确定这不能回答你的问题,但可能会给你一些想法,让你的生活更轻松。这是解决问题的 javascript 方法,但这样您甚至不必考虑对任何内容进行排序。您只需提供父母和孩子,它就会为您分类并准备好使用。在我看来是一个非常好的方式。然而,它可能与您尝试做的事情无关,但对于其他一些类似的问题,您可能会将其视为解决方案:https ://developers.google.com/chart/interactive/docs/gallery/orgchart

于 2012-05-23T10:37:32.543 回答
0

解决这个问题的唯一方法是使用自下而上的方法(我指的是金字塔)。

解释

我们需要从数组中没有父项的行(条目)开始。就我而言,它是任何具有“parent_id = 0”的元素。一旦我们有了这些,我们需要为每个父元素构建子元素。

后一部分将通过调用排序方法递归地完成,直到我们正在处理的元素没有子元素。排序方法的结果将向下传递到前一个数组点,直到数组完成。

代码

Class Categories {
    private $cats;

    public function getAllCategoriesSorted() {
        /**
         * $this->cats = [
         *      'id' => x, 'parent_id' => x
         * ];
         */
        $this->cats = Category::get()->toArray();

        # find categories with no parents
        $keys = array_keys(array_column($this->cats, 'parent_id'), 0);

        $return = [];
        # loop through each and populate each one
        foreach ($keys as $key) {
            $return[$this->cats[$key]['id']] = $this->sortCategories($this->cats[$key]);
        }

        dd($return);
    }

    private function sortCategories($currentElement) {
        # we need to check if current element has any children
        $keys = array_keys(array_column($this->cats, 'parent_id'), $currentElement['id']);

        if ($keys === false || empty($keys)) {
            # we are dealing with childless element, we should return it as it is
            return $currentElement;
        }

        # we are dealing with element that has children, we need to loop through each child
        $currentElement['children'] = [];

        foreach ($keys as $key) {
            $currentElement['children'][$this->cats[$key]['id']] = $this->sortCategories($this->cats[$key]);
        }

        return $currentElement;
    }
}

示例结果

array:2 [▼
  65 => array:4 [▼
    "id" => 65
    "name" => "Parent 1"
    "parent_id" => 0
    "children" => array:14 [▼
      66 => array:4 [▼
        "id" => 66
        "name" => "Child 1"
        "parent_id" => 65
        "children" => array:22 [▶]
      ]
      87 => array:4 [▼
        "id" => 87
        "name" => "Child 2"
        "parent_id" => 65
        "children" => array:31 [▶]
      ]
      117 => array:4 [▶]
      118 => array:4 [▶]
      120 => array:4 [▶]
      124 => array:4 [▶]
      125 => array:4 [▶]
      127 => array:4 [▶]
      225 => array:4 [▶]
      305 => array:4 [▶]
      434 => array:4 [▶]
      321 => array:4 [▶]
      348 => array:4 [▶]
      468 => array:4 [▶]
    ]
  ]
  64 => array:4 [▼
    "id" => 64
    "name" => "Parent 2"
    "parent_id" => 0
    "children" => array:5 [▼
      128 => array:4 [▶]
      132 => array:4 [▼
        "id" => 132
        "name" => "Child 3"
        "parent_id" => 64
        "children" => array:22 [▼
          202 => array:3 [▶]
          203 => array:3 [▼
            "id" => 203
            "name" => "Child 4"
            "parent_id" => 132
          ]
          204 => array:3 [▶]
          205 => array:3 [▶]
          206 => array:3 [▶]
          207 => array:3 [▶]
          208 => array:3 [▶]
          209 => array:3 [▶]
          210 => array:3 [▶]
          211 => array:3 [▶]
          212 => array:3 [▶]
          213 => array:3 [▶]
          214 => array:3 [▶]
          215 => array:3 [▶]
          216 => array:3 [▶]
          217 => array:3 [▶]
          218 => array:3 [▶]
          220 => array:3 [▶]
          221 => array:3 [▶]
          222 => array:3 [▶]
          223 => array:3 [▶]
          224 => array:3 [▶]
        ]
      ]
      134 => array:4 [▶]
      394 => array:4 [▶]
      454 => array:4 [▶]
    ]
  ]
]
于 2017-09-05T10:35:52.090 回答