Voting

Category

real language

Bookmarking

Del.icio.us Digg Diigo DZone Earthlink Google Kick.ie
Windows Live LookLater Ma.gnolia Reddit Rojo StumbleUpon Technorati

Language Javascript

(Fully commented, OOP approach.)

Date:03/28/08
Author:Ariel Flesler
URL:http://flesler.blogspot.com
Comments:0
Info:http://www.w3schools.com/js
Score: (2.96 in 27 votes)
/**
 * @projectDescription Javascript snippet to generate the lyrics of the song "99 Bottles".
 * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * Date: 3/27/2008
 * @author Ariel Flesler
 * --This script follows the standard specified by scriptDoc: http://scriptdoc.org/
 */

/**
 * @classDescription This class generates the lyrics of the song "99 Bottles".
 * @return { Song }	Returns a new Song Object.
 * @constructor
 */
var Song = function(){};

//add methods to the prototype, to affect the instances of the class Song
Song.prototype = {
	/**
	 * Maps an array of items using a function.
	 * @param { Array } src Source array whose items will be mapped.
	 * @param { Function } fn Function that receives each item & index and returns the mapped item.
	 * @return { Array } The mapped array.
	 * @method
	 * http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:map
	 */
	map: function( src, fn ){
		var 
			mapped = [ ], //will hold the mapped items
			pos = src.length; //holds the actual index

		//do a reversed loop as we know the last index
		while( pos-- )
			mapped[pos] = fn.call( this, src[pos], pos );
		
		return mapped;
	},
	/**
	 * @param { Number } amount Specifies the # of bottle.
	 * @return { String } The related text.
	 * @method
	 */
	bottle:function( left ){
		switch( left ){
			case 0: return 'no more bottles';
			case 1: return '1 bottle';
			default: return left + ' bottles';
		}
	},
	/**
	 * @param { Number } amount The amount of bottles to buy.
	 * @method
	 */
	buy:function( amount ){
		this.bottles = Array(amount+1);
	},
	/**
	 * @param { String } separator String to separate each line.
	 * @return { String } Lyrics of the song.
	 * @method
	 */
	sing:function( separator ){
		var lines =  this.map( this.bottles, function( bottle, left ){
			
			bottle = this.bottle( left );//the text for this bottle, and then the next one.
			var nextBottle = left - 1 + ( left ? 0 : this.bottles.length );
			nextBottle = this.bottle( nextBottle );
			
			return this.apply( this.line1, bottle ) + separator +					
					this.apply( left ? this.line2a : this.line2b, nextBottle );
		});
		
		return lines.reverse().join( separator+separator );
	},
	caseRegex: /%([ul])/g, //matches %u or %l
	/**
	 * @param { String } template String template of the line.
	 * @param { String } bottle The text for this bottle.
	 * @return { String } The parsed template.
	 * @method
	 */
	apply:function( template, bottle ){
		return template.replace( this.caseRegex, function( all, kase ){
			return kase == 'l' ? bottle //lowercase
				: bottle.charAt(0).toUpperCase() + bottle.slice(1); //uppercase
		});	
	},
	line1: '%u of beer on the wall, %l of beer.',
	line2a: 'Take one down and pass it around, %l of beer on the wall.',
	line2b: 'Go to the store and buy some more, %l of beer on the wall.'
};

var bottlesSong = new Song();
bottlesSong.buy( 99 );

var lyrics = bottlesSong.sing( '<br />' );

document.body.innerHTML = lyrics;

Download Source | Write Comment

Alternative Versions

VersionAuthorDateCommentsRate
Eponymous obfuscated versionJavaScribe01/09/094
using DOM and a closureChristof Donat03/07/060
3Brian Patrick Lee04/20/053
With english numbers, DOM, and callbacksJoseph Taylor01/18/080

Comments

Download Source | Write Comment

Add Comment

Please provide a value for the fields Name, Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.

Please don't post large portions of code here! Use the form to submit new examples or updates instead!

Name:

eMail:

URL:

Security Code:
  
Comment: