1

Im looking for a "good" way to display the opening times of a location.

I have given a array with opening times like this:

map[1] = '10:00 - 18:00';
map[2] = '10:00 - 18:00';
map[3] = '09:00 - 18:00';
map[4] = '10:00 - 18:00';
map[5] = '10:00 - 18:00';
map[6] = '12:00 - 23:00';

And want to get a output for the given array like here :

Mo - Tu: 10:00 - 18:00
Wednesday: 09:00 - 18:00
Th - Fr: 10:00 - 18:00
Saturday: 12:00 - 23:00
Sunday: Closed

In this case sunday is closed because map[0] is missing.

3
  • What is the HTML used to hold the values? Are they in <div>s? How are you adding those values into the HTML show that code. If you are just inserting the raw value as someDiv.innerHTML = [DAY_NAME] + map['n']; Then I would suggest splitting them into two divs, setting a class for the day and time and a width for each and having their display be table-cell or something. Commented Mar 14, 2014 at 23:02
  • 1
    I just answered an almost identical question yesterday: stackoverflow.com/questions/22392490/… Commented Mar 14, 2014 at 23:04
  • Do you realize that map['1'] isn't really Array syntax? Arrays take numeric indexes. Commented Mar 14, 2014 at 23:14

2 Answers 2

2

This one is shorter.

Use index 7 as a sentinel, and do one loop to get the output.

DEMO.

function foo( map ) {
    var names = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
    var output = [];
    var lastidx = 0;
    var lastcont = map[0];
    for (var i = 0; i <= 7; ++i) {
        if( map[i] != lastcont || 7 == i) {
            lastcont = lastcont || "Closed";
            if( (i - 1) - lastidx > 0 ) {
                output.push( names[lastidx].slice(0,2)+" - "+names[i-1].slice(0,2)+": "+lastcont);
            }
            else {
                output.push( names[lastidx]+": "+lastcont); 
            }
            lastidx = i;
            lastcont = map[i];
        }
    };
    return output;
}

Update for Monday first

function foo( map ) {
    var mapc = map.slice();
    mapc['7'] = mapc['0'];
    var names = ["", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
    var output = [];
    var lastidx = 1;
    var lastcont = mapc[lastidx];
    for (var i = lastidx; i <= 8; ++i) {
        if( mapc[i] != lastcont || 8 == i) {
            lastcont = lastcont || "Closed";
            if( (i - 1) - lastidx > 0 ) {
                output.push( names[lastidx].slice(0,2)+" - "+names[i-1].slice(0,2)+": "+lastcont);
            }
            else {
                output.push( names[lastidx]+": "+lastcont); 
            }
            lastidx = i;
            lastcont = mapc[i];
        }
    }
    return output;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Can u modify it so, that it always Starts with Monday if available and not sunday. I tried it on my own but couldnt bring it to work
1

Assuming you actually meant numeric indexes since you said "Array", here's a way to do it. The basic algorithm is that we create a bucket item that keeps track of the start day and end day for the current time. As we go through the array, if we find the same start/end time as what is in the bucket, we just update the end day. When we encounter a different set of start/end times, we push the current bucket onto the results array and start a new bucket with the new start/end times. When we're done, we have an array of buckets that tell us which buckets of start times we have and that can then be converted to a text form.

var map = [];
map[1] = '10:00 - 18:00';
map[2] = '10:00 - 18:00';
map[3] = '09:00 - 18:00';
map[4] = '10:00 - 18:00';
map[5] = '10:00 - 18:00';
map[6] = '12:00 - 23:00';

function processHours() {

    var shortNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    var longNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

    function makeBucket(day, hours) {
        var bucket = {};
        bucket.startDay = bucket.endDay = day;
        bucket.value = hours;
        bucket.hours = hours ? hours: "Closed";
        return bucket;
    }

    var buckets = [];
    var curBucket;
    for (var i = 0; i < 7; i++) {
        if (!curBucket) {
            curBucket = makeBucket(i, map[i]);
        } else {
            // if the current bucket has the same value as this day
            // then extend the range of the bucket
            if (map[i] === curBucket.value) {
                curBucket.endDay = i;            
            } else {
                // take current bucket and put it on the array
                buckets.push(curBucket);

                // start a new bucket
                curBucket = makeBucket(i, map[i]);            
            }
        }
    }
    // put last curBucket into the array
    buckets.push(curBucket);

    // now turn the set of buckets into array of strings
    var output = [];
    for (var i = 0; i < buckets.length; i++) {
        curBucket = buckets[i];
        // process single days different than multi-days
        if (curBucket.startDay === curBucket.endDay) {
            output.push(longNames[curBucket.startDay] + ": " + curBucket.hours);
        } else {
            output.push(shortNames[curBucket.startDay] + " - " + 
                        shortNames[curBucket.endDay] + ": " +
                        curBucket.hours);
        }
    }
    return output;
}

Working demo: http://jsfiddle.net/jfriend00/rn9VC/

This returns the data in the order presented so Sunday would come first. If you want to put special case Sunday to go last, you can tweak the output to present it that way.

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.