HL Menu - Data Structure

by ethan_selzer

HTML

<h3>Requirements</h3>
<ol>
    <li>Create a data structure for displaying a list of "events" in up-to four columns.</li>
    <li>Columns should fill up from left to right and contain a maximum of 16 events</li>
    <li>Each event will fall into one of two categories: upcoming or starting soon.</li>
    <li>The "upcoming" events should be displayed before the "starting soon" events.  The "starting soon" events should always start a new column.</li>
    <li>In case there are more than 4 * 16 events, ignore the 16-event limit per column and balance the number of items per column to minimize the height of the view</li>
</ol>

CSS

@import url('http://twitter.github.com/bootstrap/assets/css/bootstrap.css');

body{margin: 10px;}
ol{list-style-type:decimal;}

JavaScript

var eventsMenu = ( function(){
    function getNewEvents( events ){
        return _.filter( events, function( event, index ){
            return ! event.isEndingSoon;
        } );
    }
    
    function getEndingSoonEvents( events ){
        return _.filter( events, function( event, index ){
            return event.isEndingSoon;
        } );
    }
    
    function addEventsListLabel( events, label ){
        events.unshift( label );
        return events;
    }
    
    function getNewEventsWithLabel( events, label ){
        return addEventsListLabel( getNewEvents( events ), label );   
    }
    
    function getEndingSoonEventsWithLabel( events, label ){
        return addEventsListLabel( getEndingSoonEvents( events ), label );   
    }
    
    function getAdjustedColumnLength( desiredColumnLength, newEventCount, endingSoonEventCount ){
        var eventColumnCount = getColumnCount( newEventCount, desiredColumnLength );
        var upcomingEventColumnCount = getColumnCount( endingSoonEventCount, desiredColumnLength );
        var combinedColumnCount = eventColumnCount + upcomingEventColumnCount;
        if( combinedColumnCount > 4 ){
            return getAdjustedColumnLength( desiredColumnLength + 1, newEventCount, endingSoonEventCount );
        }
        return desiredColumnLength;
    }
    
    function getColumnCount(  eventCount, columnLength ){
        return Math.ceil( eventCount / columnLength );
    }
    
    function makeColumns( columnLength, events ){
        var eventsCollection = [];
        events = events.slice( 0 );
        while( events.length > 0 ){
            eventsCollection.push( events.splice( 0, columnLength ) );     
        }   
        return eventsCollection;
    }
    
    function getColumnCollection( columnLength, newEvents, endingSoonEvents ){
        var newEventsColumns = makeColumns( columnLength, newEvents );
        var endingSoonEventsColumns = makeColumns( columnLength, endingSoonEvents );
        return...