简体   繁体   中英

Hierarchical Sorting of Categories in Javascript

I'm trying to sort categories like those given below in a hierarchical manner, and then later output them to a web page. I know for a fact that I need to use some form of recursion since the categories could possess any level of depth. I'd also like to be able to sort those categories on the same depth level by alphabetical order, which I know I can do using the someArray.sort() method.

Ideally, I would have something structured like this, with each name being an object in the tree, and it's term_id as its index in the array:

0 Computer Technology
0 --> Hardware
0 ----> Microprocessors
0 ----> Hard Drives
0 --> Software
0 ----> Firmware & Embedded Systems
0 ----> Operating Systems
0 ----> Web and Internet-Based Applications
0 Uncategorized

So far I've looked through many questions on the site and haven't been able to clearly adapt any one of them for my needs. Here's where I've gotten so far:

function hierarchicalSort( categories, sorted, parentID ) {
    for( var i = 0; i < categories.length; i++ ) {
        if( categories[i] === null )
        {
            continue;   // There may be more categories to sort
        }
        else if( categories[i].parent == parentID ) {
            sorted.push( categories[i] ); // Same parent ( same level )
            categories[i] = null;   // Our "Already Sorted" flag
        }
        else {
            sorted[categories[i].term_id].children = [];
            // This category has a different parent
            hierarchicalSort( categories, sorted, categories[i].term_id );
            // Find this category's children
        }
    }
}

I have categories with the following information:

var categories = [
    {
        term_id: 1,
        name: Uncategorized,
        parent: 0,
        count: 1
    },
    {
        term_id: 2,
        name: Hardware,
        parent: 7,
        count: 1
    },
    {
        term_id: 3,
        name: Software,
        parent: 7,
        count: 2
    },
    {
        term_id: 7,
        name: Computer Tech,
        parent: 0,
        count: 0
    },
    {
        term_id: 8,
        name: Operating Systems,
        parent: 3,
        count: 1
    },
    {
        term_id: 9,
        name: Firmware and Embedded Systems,
        parent: 3,
        count: 0
    },
    {
        term_id: 10,
        name: Web and Internet-Based Applications,
        parent: 3,
        count: 0
    },
    {
        term_id: 11,
        name: Hard Drives,
        parent: 7,
        count: 3
    },
    {
        term_id: 23,
        name: Microprocessors,
        parent: 7,
        count: 1
    }
];

My Proposed Solution:

Use the array of categories as a queue, and examine each of the categories as the while loop runs.

/**
 * Creates a category tree structure from a list of objects.
 * 
 * @param {array} categories: The list of categories to sort into a hierarchical tree.
 * It is mainly accessed as a queue to ensure that no category is missed during each
 * generation of the tree level.
 * 
 * @param {array} sorted: The "treeified" structure of categories
 * @param {int} parentID: The ID of the parent category
 * 
 * @since 0.2.0
 * 
 * @returns {undefined}
 */
function hierarchicalSort( categories, sorted, parentID )
{
    /**
     * Term Iterator var i: Goal is to go through each category at least once
     */
    var i = categories.length;

    // This loop completes a full cycle through categories for each depth level
    while( --i >= 0 ) { 
        // Pull the category out from the sorting "queue"
        var category = categories.shift();  
        if( category.parent == parentID ) {
            sorted.push( category ); // Same parent
        }
        else {
            categories.push( category ); // Uhh, this category has a different parent...
            // Put it back on the queue for sorting at a later time
        }
    }

    // Keep going until you hit the end of the array
    for( var j = 0; typeof sorted[j] !== 'undefined'; j++ ) {
        sorted[j].children = [];

        /**
         * Find this category's children, by importing the remaining queue,
         * giving the current sorted category's children property, and the 
         * current sorted category's term_id
         */
        hierarchicalSort( categories, sorted[j].children, sorted[j].term_id );
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM