3
\$\begingroup\$

I've been spending lot of time reading through this site and found plenty of resources that shaped up my code.

I am working on an open source project known as Quizz. It is in a primitive stage as I work only during my spare time I cannot concentrate much. For this JavaScript to work, I have a huge objects and array's of topics and questions in a variable called qbank (read question bank).

var qbank   = {};

qbank['js'] = [];
qbank['html']   = [];

qbank['js'].push({
    level:  'basic',
    questions:  [
        {
            title:  'One JS BASIC A question statement?',
            type:   'single',                       
            anss:   [
                'Answer 1',
                'Answer 2',
                'Answer 3'
            ],
            ans:    [1],
            comments:   'If there is a wrong answer, a justification is needed'

        },

    ]
});

I guess from the above code it is understandable that the topics may be JavaScript/HTML/PHP or Java, and each JavaScript array holds set of questions based on levels (basic, intermediate,... advanced).

The idea is to iterate over array and hold each levels and topics in a separate array variable.

Do you think this approach is good? I really feel there is something wrong with this.

var digest  = function() {      
        for( var q in qbank ) {
            //  q   is js/html/php/..... topic names    
            var
                topic,
                t,
                qns     = 0,
                i   = 0,
                questions,
                question,
                level
            ;

            topic   = qbank[q];

            //  Initializing instance topics
            _instance.topics[q]= [];

            for( 
                var 
                    l = levels.length
                ; i < l; i++ ) {

                if( typeof _instance.topics[q][i] === 'undefined' ) {
                    _instance.topics[q][i]  = {
                        'level': levels[i],
                        'questions': []
                    };
                }
            }

            for( t in topic ) {
                questions   = topic[t].questions;
                level       = topic[t].level;

                for( qns in questions ) {                   
                    for( var 
                            inst = 0, 
                            l = _instance.topics[q].length; inst < l; inst++ ) {

                        if( _instance.topics[q][inst].level === level ) {
                            _instance.topics[q][inst].questions.push( questions[qns] );
                        }
                    }
                }
            }
        }
    };

Secondly, I have this digest function where it will pull out and merge all the questions based on levels and topics. I really hate to see my code with plenty of for loops. Please help in suggesting a good practice or approach I need to take.

\$\endgroup\$
2
\$\begingroup\$

I can understand your frustration of nested for loops.

However, your data structure is full of nested arrays. How else can you handle them?

One way to have pretty code is to separate each loop in its own function, with clear names.

This way, the main logic remains readable. And if you want to go in detail, the only scope you have to care about is a small function.

You can refactor more than in the example given above, it's all up to you.

Example:

var digest  = function() {      
        for( var q in qbank ) {
            //  q   is js/html/php/..... topic names    
            var
                topic,
                t,
                qns     = 0,
                i   = 0,
                questions,
                question,
                level
            ;

            topic   = qbank[q];

            initInstance( _instance, q );

            for( t in topic ) {
                initTopics( _instance, t, q );

            }
        }

        //  Initializing instance topics
        function initInstance( _instance, q ) {
            _instance.topics[q]= [];

            for( 
                var 
                    l = levels.length
                ; i < l; i++ ) {

                if( typeof _instance.topics[q][i] === 'undefined' ) {
                    _instance.topics[q][i]  = {
                        'level': levels[i],
                        'questions': []
                    };
                }
            }
        }

        function initTopics( _instance, t, q ) {
            var
                questions   = topic[t].questions,
                level       = topic[t].level
            ;

            for( qns in questions ) {                   
                for( var 
                        inst = 0, 
                        l = _instance.topics[q].length; inst < l; inst++ ) {

                    if( _instance.topics[q][inst].level === level ) {
                        _instance.topics[q][inst].questions.push( questions[qns] );
                    }
                }
            }
        }
};
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ +1 for this suggestion, my bad it didn't hit me in the first place about using functions. Now I can break down topics and levels based on your suggestion. TY! \$\endgroup\$ – Srini Sekhar Jun 19 '13 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.