Mr Pablo
Mr Pablo

Reputation: 4188

Checking for time conflicts, want to show just 1 warning

I have a form where the user can add X number of rows, with each row having a start time and end time input.

The rows can be added as the user likes, and the times do not have to be entered sequentially, but must not conflict when submitting the form.

So far, I am able to check for conflicts, using a couple of for loops and checking each start and end time against the rest.

The problem I am facing, is that obviously, if row 1 and 2 conflict, my code is logging two conflicts (logically correct!)

I only want to show the first conflict, as once this is resolved, naturally, the second conflict is.

My code for far:

$('form').submit(function(event){
                event.preventDefault();

                var errors = [];

                var data = serializedToObject($(this).serializeArray());

                for(var i = data.row.length; i--;) {                        
                    for(var s = data.start.length; s--;) {
                        if(s != i) {
                            if(data.start[i] < data.end[s] && data.start[s] < data.end[i]) {
                                errors.push('Conflict between ' + data.row[i] + ' and ' + data.row[s]);
                            }
                        }
                    }
                }

                if(errors.length === 0) {
                    this.submit();
                } else {
                    console.log(errors);
                }
            });

(serializedToObject simply converts the form data to an object)

So how do I have my code only push 1 of the conflicts to the array?

I tried adding the row ID to an object and pushing that to the array, but it wouldn't log additional conflicts later down the line e.g. Row 1 conflicts with 2 and 4, the conflicts between 1 and 4 would not be mentioned, as row 1 is already in the array.

Upvotes: 1

Views: 93

Answers (1)

ali404
ali404

Reputation: 1153

I have an answer for you, but it is not that efficient (again O(n^2), as you code in the question ).

If i understood correctly , data.start.length and data.row.length has to be equal, right? If so, if you count the s from i-1 to 0, and the errors are (1,2) and (2,1) , (1,2) won't get cought becouse the second loop starts from i-1, in the case where i=1, s starts directly from 0. just take a look at the code below (only included the for loops) :

var length = data.row.length;

for( var i = length; i>0; i-- ) {
    for( var s = i-1; s>0; s-- ) {
        if(data.start[i] < data.end[s] && data.start[s] < data.end[i]) {
         errors.push('Conflict between ' + data.row[i] + ' and ' + data.row[s]);
      }
    }
}

I hope somebody will come with a comment with an idea to optimise this, maybe O(n) if it is possible :D. But this will work for you , and in case where you don't have length variable as big as 100.000, it will work just swell!

Upvotes: 2

Related Questions