0

This is an output array pushed from mysql query

Array
(
    [0] => Array
        (
            [CategoryID] => 7
            [CategoryName] => Test it
            [Parent] => 2
            [Thumb] => 4
            [sort] => 0
            [MediaID] => 4
            [MediaTitle] => asd
            [MediaName] => 1349012691_4.jpg
            [MediaType] => image
            [MediaSize] => 369848
            [UploadTime] => 1349012691
        )

    [1] => Array
        (
            [CategoryID] => 8
            [CategoryName] => Test all
            [Parent] => 4
            [Thumb] => 5
            [sort] => 0
            [MediaID] => 5
            [MediaTitle] => asaas
            [MediaName] => 1349012728_9.jpg
            [MediaType] => image
            [MediaSize] => 416817
            [UploadTime] => 1349012728
        )

    [2] => Array
        (
            [CategoryID] => 4
            [CategoryName] => Test Image
            [Parent] => 0
            [Thumb] => 0
            [sort] => 2
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

    [3] => Array
        (
            [CategoryID] => 2
            [CategoryName] => Test Sub
            [Parent] => 1
            [Thumb] => 0
            [sort] => 4
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

    [4] => Array
        (
            [CategoryID] => 3
            [CategoryName] => Test Category
            [Parent] => 0
            [Thumb] => 0
            [sort] => 6
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

    [5] => Array
        (
            [CategoryID] => 1
            [CategoryName] => Test Category
            [Parent] => 0
            [Thumb] => 0
            [sort] => 8
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

    [6] => Array
        (
            [CategoryID] => 5
            [CategoryName] => Test Category
            [Parent] => 0
            [Thumb] => 0
            [sort] => 10
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

    [7] => Array
        (
            [CategoryID] => 6
            [CategoryName] => Test Remove
            [Parent] => 0
            [Thumb] => 0
            [sort] => 12
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

)

I need to sort this array so it show Parents Category First then child categories.

I need the output something like

Array
(

    [2] => Array
        (
            [CategoryID] => 4
            [CategoryName] => Test Image
            [Parent] => 0
            [Thumb] => 0
            [sort] => 2
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )
        //sub category
            [1] => Array
            (
                [CategoryID] => 8
                [CategoryName] => Test all
                [Parent] => 4
                [Thumb] => 5
                [sort] => 0
                [MediaID] => 5
                [MediaTitle] => asaas
                [MediaName] => 1349012728_9.jpg
                [MediaType] => image
                [MediaSize] => 416817
                [UploadTime] => 1349012728
            )

    [3] => Array
        (
            [CategoryID] => 2
            [CategoryName] => Test Sub
            [Parent] => 1
            [Thumb] => 0
            [sort] => 4
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )
                //sub category
                [0] => Array
                (
                    [CategoryID] => 7
                    [CategoryName] => Test it
                    [Parent] => 2
                    [Thumb] => 4
                    [sort] => 0
                    [MediaID] => 4
                    [MediaTitle] => asd
                    [MediaName] => 1349012691_4.jpg
                    [MediaType] => image
                    [MediaSize] => 369848
                    [UploadTime] => 1349012691
                )

    [4] => Array
        (
            [CategoryID] => 3
            [CategoryName] => Test Category
            [Parent] => 0
            [Thumb] => 0
            [sort] => 6
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

    [5] => Array
        (
            [CategoryID] => 1
            [CategoryName] => Test Category
            [Parent] => 0
            [Thumb] => 0
            [sort] => 8
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

    [6] => Array
        (
            [CategoryID] => 5
            [CategoryName] => Test Category
            [Parent] => 0
            [Thumb] => 0
            [sort] => 10
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

    [7] => Array
        (
            [CategoryID] => 6
            [CategoryName] => Test Remove
            [Parent] => 0
            [Thumb] => 0
            [sort] => 12
            [MediaID] => 
            [MediaTitle] => 
            [MediaName] => 
            [MediaType] => 
            [MediaSize] => 
            [UploadTime] => 
        )

)

Can I do this with PHP?

8
  • 1
    This is not sorting but grouping based on parent id .. Please correct me if am wrong ?? Commented Sep 30, 2012 at 14:25
  • Sure you can, but if its wise? Commented Sep 30, 2012 at 14:25
  • @JvdBerg yes i think its wise because if i sort it i won't have to loop through 2 arrays to list Child Categories under Parents Category Commented Sep 30, 2012 at 14:34
  • 1
    And what if your tree contains a million entries and is nested many levels deep, are you gonna fetch them all an sort them? Commented Sep 30, 2012 at 14:36
  • 1
    The correct strategy for this kind of problems is to fetch the top leafs, and when a detail is needed only fetch that detail. Commented Sep 30, 2012 at 14:39

3 Answers 3

1

You can try

# Short Version of your Array
$oldList = Array(
    "0" => Array("CategoryID" => 7,"CategoryName" => "Test it","Parent" => 2),
    "1" => Array("CategoryID" => 8,"CategoryName" => "Test all","Parent" => 4),
    "2" => Array("CategoryID" => 4,"CategoryName" => "Test Image","Parent" => 0),
    "3" => Array("CategoryID" => 2,"CategoryName" => "Test Sub","Parent" => 1),
    "4" => Array("CategoryID" => 3,"CategoryName" => "Test Category","Parent" => 0),
    "5" => Array("CategoryID" => 1,"CategoryName" => "Test Category","Parent" => 0),
    "6" => Array("CategoryID" => 5,"CategoryName" => "Test Category","Parent" => 0),
    "7" => Array("CategoryID" => 6,"CategoryName" => "Test Remove","Parent" => 0)
);

echo "<pre>";
print_r(__group($oldList));

Function used

function __group($oldList)
{
    # Get Category Position
    $category = array_map(function($item) { return $item['CategoryID'];}  ,$oldList); 

    #Get Only Parent List and add to new list
    $newList = array_filter($oldList , function($item) {  return $item['Parent']  == 0 ; } );

    foreach($oldList as $key => $value)
    {
        if($value['Parent'] != 0) {
            # Mapt Chiled to parent using Parent ID & Category ID 
            $newList[array_search($value['Parent'],$category)]['child'][] = $value;
        }
    }
    return $newList ;
}

Output

Array
(
    [2] => Array
        (
            [CategoryID] => 4
            [CategoryName] => Test Image
            [Parent] => 0
            [child] => Array
                (
                    [0] => Array
                        (
                            [CategoryID] => 8
                            [CategoryName] => Test all
                            [Parent] => 4
                        )

                )

        )

    [4] => Array
        (
            [CategoryID] => 3
            [CategoryName] => Test Category
            [Parent] => 0
        )

    [5] => Array
        (
            [CategoryID] => 1
            [CategoryName] => Test Category
            [Parent] => 0
            [child] => Array
                (
                    [0] => Array
                        (
                            [CategoryID] => 2
                            [CategoryName] => Test Sub
                            [Parent] => 1
                        )

                )

        )

    [6] => Array
        (
            [CategoryID] => 5
            [CategoryName] => Test Category
            [Parent] => 0
        )

    [7] => Array
        (
            [CategoryID] => 6
            [CategoryName] => Test Remove
            [Parent] => 0
        )

    [3] => Array
        (
            [child] => Array
                (
                    [0] => Array
                        (
                            [CategoryID] => 7
                            [CategoryName] => Test it
                            [Parent] => 2
                        )

                )

        )

)
Sign up to request clarification or add additional context in comments.

Comments

0

You can use code bellow. This will group array and sort every array(root and child arrays) depending on sort key. To retrieve new grouped/sorted array use this $newArray = groupMe($originalArray);

function groupMe($array) {
    $returningArray = array();

    $mapCatIdCategory = array();
    //first pass create mapCatIdCategory
    foreach ($array as &$item) {
        $mapCatIdCategory[$item['CategoryId']] = &$item;
        $item['child'] = array();
    }

    //second pass is for setting child
    foreach ($array as &$item) {
        $parentId = $item['Parent'];
        if ($parentId == 0) {   //no parent category => add to root
            $returningArray[] = &$item;
        }
        else if (isset($mapCatIdCategory[$parentId])){ //not sure if data is always valid
            $mapCatIdCategory[$parentId]['child'][] = &$item; 
        }
    }

    //third pass sort root and all child array(recursively)
    recursiveSort($returningArray);

    return $returningArray;
}

function recursiveSort(&$array) {
    foreach ($array as &$item) {
        if (count($item['child']) >  1) { //empty or 1 elements arrays are already sorted
            recursiveSort($item['child']); //sort child
        }
    }

    usort($array, "cmpCategory"); //sort array by user comparasion function
}

function cmpCategory($a, $b) {
    if ($a['sort'] == $b['sort']) {
        return 0;
    }
    return ($a['sort'] < $b['sort']) ? -1 : 1;
}

Comments

0

This will group entries as you want:

function groupData($data) {
    $tree = array();
    $waiting = array();
    $index = array();
    foreach ($data as &$entry) {
        $index[$entry['CategoryID']] = &$entry;
        if (isset($waiting[$entry['CategoryID']])) {
            $entry['children'] = &$waiting[$entry['CategoryID']];
        } else {
            $entry['children'] = array();
        }
        if ($entry['Parent']) {
            if (isset($index[$entry['Parent']])) {
                $index[$entry['Parent']]['children'][] = &$entry;
            } else {
                if (!isset($waiting[$entry['Parent']])) {
                    $waiting[$entry['Parent']] = array();
                }
                $waiting[$entry['Parent']][] = &$entry;
            }
        } else {
            $tree[] = &$entry;
        }
    }
    return $tree;
}

If you need also to sort results by 'sort' attribute, some name or anything else best would be to do that in your SQL query. Function above will not change records order.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.