Improved way to build nested array of unique values in javascript
        Posted  
        
            by 
                dualmon
            
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by dualmon
        
        
        
        Published on 2012-11-29T10:37:54Z
        Indexed on 
            2012/11/29
            11:04 UTC
        
        
        Read the original article
        Hit count: 252
        
The setup:
I have a nested html table structure that displays hierarchical data, and the individual rows can be hidden or shown by the user. Each row has a dom id that is comprised of the level number plus the primary key for the record type on that level. I have to have both, because each level is from a different database table, so the primary key alone is not unique in the dom.
example: id="level-1-row-216"
I am storing the levels and rows of the visible elements in a cookie, so that when the page reloads the same rows the user had open are can be shown automatically. I don't store the full map of dom ids, because I'm concerned about it getting too verbose, and I want to keep my cookie under 4Kb.
So I convert the dom ids to a compact json object like this, with one property for each level, and a unique array of primary keys under each level:
{
    1:[231,432,7656],
    2:[234,121],
    3:[234,2],
    4:[222,423],
    5:[222]
}
With this structure stored in a cookie, I feed it to my show function and restore the user's previous disclosure state when the page loads.
The area for improvement:
I'm looking for better option for reducing my map of id selectors down to this compact format. Here is my function:
function getVisibleIds(){
    // example dom id: level-1-row-216-sub
    var ids = $("tr#[id^=level]:visible").map(function() {
        return this.id;
    });
    var levels = {};
    for(var i in ids ) { 
        var id    = ids[i];
        if (typeof id == 'string'){
            if (id.match(/^level/)){
                // here we extract the number for level and row
                var level = id.replace(/.*(level-)(\d*)(.*)/, '$2');
                var row   = id.replace(/.*(row-)(\d*)(.*)/, '$2');
                // *** Improvement here? ***
                // This works, but it seems klugy. In PHP it's one line (see below):
                if(levels.hasOwnProperty(level)){
                if($.inArray(parseInt(row, 10) ,levels[level]) == -1){
                        levels[level].push(parseInt(row, 10));
                }
                } else {
                    levels[level] = [parseInt(row, 10)];
                }
            }
        }
    }
    return levels;
}
If I were doing it in PHP, I'd build the compact array like this, but I can't figure it out in javascript:
foreach($ids as $id) {
    if (/* the criteria */){
         $level = /* extract it from $id */;
         $row   = /* extract it from $id */;
         $levels[$level][$row];
    }
}
© Stack Overflow or respective owner