Friday, May 13, 2011

generate combinations of elements from multiple arrays

Problem: we have multiple arrays, and we must find all combinations of the elements of these arrays. For example, if we have two array:

$option1 = array('apple', 'orange', 'pear');
$option2 = array('rice', 'noodle');

And we must find all combinations(there are 6 of them in this example) of these two array elements:

'apple', 'rice',
'apple', 'noodle',
'orange', 'rice',
'orange', 'noodle',
'pear', 'rice',
'pear', 'noodle'

First, let's see how to implement the algorithm in PHP:

//$allOptionsArray is an array containing all options array
//$final is a stdClass
function getCombinations($allOptionsArray, $final) {
    if(count($allOptionsArray)) {
        for($i=0; $i < count($allOptionsArray[0]); $i++) {
            $tmp = $allOptionsArray;
            $final->codes[$final->pos] = $allOptionsArray[0][$i];
            array_shift($tmp);
            $final->pos++;
            getCombinations($tmp, $final);
        }
    } else {
        $final->result[] = $final->codes;
    }
    $final->pos--;
}
//let's see how to use the function:
$option1 = array('apple', 'orange', 'pear');
$option2 = array('rice', 'noodle');
$allOptionsArray = array($option1, $option2);
$final = new stdClass();
$final->result = array();
$final->codes  = array();
$final->pos    = 0;
getCombinations($allOptionsArray, $final);
//$final->result is an array containing all possible combinations
var_dump($final->result);

We can easily implement same algorithm in javascript:

var getCombinations = function(allOptionsArray, combination) {
    if(allOptionsArray.length > 0) {
        for(var i=0; i < allOptionsArray[0].length; i++) {
            var tmp = allOptionsArray.slice(0);
            combination.codes[combination.counter] = allOptionsArray[0][i];
            tmp.shift();
            combination.counter++;
            getCombinations(tmp, combination);
        }
    } else {
        var combi = combination.codes.slice(0);
        combination.result.push(combi);
    }
    combination.counter--;
}

//use it:
var a = ["01", "02", "03", "04"];
var b = ["white", "green", "blue", "red"];
var c = ["one", "two", "three", "four"];
var d = ["a", "b", "c", "d"];

var allOptionsArray = [a, b, c, d];
var combination = {codes : [], result : [], counter : 0};

getCombinations(allOptionsArray, combination);

for(var i=0; i < combination.result.length; i++) {
    console.log(combination.result[i]);
}

Thursday, May 12, 2011

use jslint.com to check your javascript code quality (and prepare to get feeling hurt)

PHP developers may know that we can use php CodeSniffer (phpcs) to check php code quality. JSLint.com to javascript is exactly same as phpcs to php. The only issue is, you have to copy and paste your code through JSLint.com. Besides that, it is a pretty cool tool to help you find out your javascript coding issues. Try hard to ensure all your javascript code can pass through its test without any error. In my last blog, i said i need to find where my code causes the problem in IE and my IDE doesn't help me a lot, i use this jslint.com to find out finally.

Since you have to copy and paste your code to the website, it is better after we finish coding in one javascript file, we immediately check this file to ensure our code is in good coding quality. Otherwise, in a big javascript project, after you already created a lot of javascript files, and then come back to check them one by one, that is gonna be painful, and that is exactly what i've been feeling.


Wednesday, May 11, 2011

javascript function practices that hardly used in other language

Function in javascript is nothing but object. That means we can create functions dynamically, assign them to other variables, pass them as parameters of other functions. Function's role in javascript is quite special. And some practices are never seen in other programming languages.

1. Functions that Return Functions

function func() {
   alert('A!');

   //return a function!
   //well, we can just think we return an object
   return function(){
      alert('B!');
   };
}

//alert A
var b = func();
//alert B
b();



In the example, the outside function func() wraps a returned function, so it creates a closure, and we can use this closure to store private data, which is accessible by the returned function but not to the outside code. Let's see another example:

var setup = function () {
    //we have a counter, when setup is called,
    //the counter is set to 0
    var counter = 0;
    //the return function can access counter, 
//but outside code cannot see it.
    return function () {
       return (counter += 1);
    };
};
// usage
var next = setup();
next(); // returns 1
next();  //returns 2
next();  //returns 3

This example is a counter that gives you an incremented value every time you call it.


2. Self-Defining Functions(Functions rewrite themself!)

var itIsWeird = function() {
      alert('javascript function is weird');
      //rewrite itself now!!!!
      itIsWeird = function() {
           alert('it is not that weird');
      };
}
//first time call the function, 
//it shows javascript function is weird
itIsWeird();

//call the function again, 
//it shows it is not that weird
itIsWeird();


Self-Defining functions could be useful when your function has some initial preparatory work to do and it needs to do it only once(maybe some init job?). Because there’s no reason to do repeating work when it can be avoided, a portion of the function may no longer be required. In such cases, the self defining function can update its own implementation. It can obviously help with the performance of your application, because your redefined function simply does less work.

These practices are hardly seen in other languages. Well, but it doesn't mean they are good practices. Take self-defining functions as example. Yes they may be useful in some cases. But a function changes its own behavior by itself? One thing i always stress is we should try to minimize things that could possibly bring confusions in software engineering, and i think self-defining function is one the things we should try to avoid. And its benefits, well, i believe we can achieve in other ways that are more readable and easier to understand.

Tuesday, May 10, 2011

copy arrays & objects in javascript

In javascript, when we assign an array or object to a variable, we are actually making a reference to the objects(array is object too). check this code:

var a = ['henry'];
//b is a reference to a
var b = a;
b[0]   = ['li'];
//we can see a[0] is changed to 'li' as well
console.log(a[0]);



In some situations, however, we may just want a copy of the object, instead of a reference.

Let's see how to deal with array first. Copying an array in javascript is surprisingly easy, thanks to the array.slice(start, end) method. The slice() method selects a part of an array, and returns the new array. It accepts two parameters: start, end. If we set start to 0, and omit the end, the method will actually return a copy of the whole array. Check this code snippet:

var a = ['henry'];
//b is a copy of a
var b = a.slice(0);
b[0]   = ['li'];
//we can see a[0] is still 'henry'
console.log(a[0]);


When it comes to an object, things are not that easy. javascript doesn't have any method for us to copy an object(one of the things i can't believe).  Fortunately, we can create a prototype method to achieve this goal.

//first, we must know that all javascript objects(function, array, custom objects) are instances of Object.
//and we just create an Object prototype clone method  
Object.prototype.clone = function() {
  //first, it check if this is an array or object
  var cloneObject = (this instanceof Array) ? [] : {};
 //now look through the object's all properties
  for (i in this) {
    //if it is clone, then contiune
    if (i == 'clone') {
        continue;
    }
    //if the property is also a type of object, recursively call the clone method
    if (this[i] && typeof this[i] == "object") {
        cloneObject[i] = this[i].clone();
    } else {
        //if it is not object type, simply copy it
        cloneObject [i] = this[i]
    }
  }
  return cloneObject;
};




It is done! Now all javascript objects will have this clone method. Let's see how to use it:



//we create a constructor function

var Person = function (){
    this.name = 'henry';
    this.getName = function(){
        return this.name;
    }
}
//get a person object
var one = new Person();
//clone this object to two
var two = one.clone();
//now let's change two's name
two.name = 'henry li';
//we can see one's name remain unchanged.
console.log(one.getName());
console.log(two.getName());


Saturday, May 7, 2011

javascript object oriented programming 5 - private members 2(object literal)

My last blog shows how to achieve privacy for objects using function constructors. How about object literals?

Check the code:

//this is the object
var newCar;

//now, let js's anonymous immediate function do the trick
(function() {
//private members
var model = 'mazda 3';

//public implementation
//don't put 'var' before the newCar!
newCar = {
     getModel : function(){return model;}
};
}());

//now, let's call the getModel method, 
//you will get 'mazda 3'
newCar.getModel();


The way it works is easy to understand as long as we know, javascript object and function can provide local scope. So we just need a function to wrap the private data. In object literals, we can use the closure created by an additional anonymous immediate function.

But do we really want to create object privacy in this way? For me, this kind of code cannot be counted elegant. My last blog suggests we can simply use naming convention to achieve object privacy. It sounds not professional, but i believe that is the easiest way: easy to implement, easy to read, easy to understand, easy to modify.

Let's accept this truth: javascript is NOT especially designed as an object oriented programming language, it is  NOT  especially designed for OOP, even though it provides with the power/magic/flexibility that you can make it an OOP language or achieve all OOP language features.

I still believe the best word to describe javascript is plasticine. You can shape it and make it look like different things.

I have to declare that I am not against using javascript to do OOP. Actually, i believe we should apply OOA/OOP to any complicated and large javascript project, a web game, for example. But i don't think it is necessary that we twist javascript to prove that it is a fully OOP language.

Thursday, May 5, 2011

javascript object oriented programming 4 - private members

Let's check the code:
Car = {
   model : 'mazda 3',
   getModel : function() {return this.model},
}
//we can access the model property directly
console.log(Car.model);
//how about we use function constructor?
var Car = function() {
    this.model = 'mazda 3';
}
var newCar = new Car;
//we still can access the model property directly.
console.log(newCar.model);


In the above examples, we can't hide object's properties from being exposed. What if we want to have private properties and private methods/functions that can be accessed only in the object, just like what we do in java and php 5?

Same as we use object scope to achieve namespace, we can also create private members for our object.
var Car = function() {
    //the model variable is only visible within the Car object now!
   //so it becomes a private property of Car
    var model = 'mazda 3';
    //since function, which is object in js, can be assigned to a variable,
    //we can have private function too!
   // this upgrade function is only visible in Car scope!
    var upgrade = function(newModel) {
        model = newModel;
    };
    //a public method.
    this.getModel = function() {
        upgrade('mazda 6');
        return model;
    }
}
var newCar = new Car();
//will get undefined
console.log(newCar.model);
//will get error
newCar.upgrade('toyota');
//will get mazda 6
newCar.getModel();


Some people say javascript is a functional programming language, some argue it is object based language because almost everything is object in javascript, while others prove that javascript can have full OOP features just like other modern object oriented programming languages like java. 

I would say, javascript is a plasticine programming language! You can shape it as whatever you want !

Actually, i think we don't even need to bother about implementing those private member stuff. If we really want to have private, we can simply use naming convention: private members must be prefixed with underscore, for example:
var Car = function() {
    this._model = '3';
    this._upgrade = function(newModel) {
        this._model = newModel;
    };
    this.getModel = function() {
        this._upgrade('mazda 6');
        return this._model;
    }
}

And then, just tell your team members to follow this coding convention: when you see something prefixed with _, you know you shall not directly access it or change its status.

Tuesday, May 3, 2011

javascript namespace

Javascript namespace is nothing but actually a global object and all other variables, functions, objects are placed in this object, so they become properties of the global object.

Code below creates two global objects:

// we have two global objects
var Category = {
     name:'books', 
     description:'all books',
     getName : function(){return this.name;},
};
var Product = {};


Now let's introduce namespace, so everything is into MyProject namespace, and MyProject is the only global variable.

var MyProject =  MyProject || {};
MyProject.Modules = MyProject.Modules || {};
MyProject.Modules.Category = {
     name:'books',
     description:'all books',
     getName : function(){return this.name;},
};
MyProject.Modules.Product = {};


What if we want to use constructor function? We can still do that:

MyProject.Models.Car = function(model) {
       this.model = model;
}
var newCar = new MyProject.Models.Car('toyota');


It is tedious every time we declare a new namespace, we have to do something like

MyProject.Modules =  MyProject.Modules || {};


Let's create a general purpose namespace function

var MyProject= MyProject || {};
MyProject.ns = function (nsName) {
     var parts = nsName.split('.'),
     parent = MyProject,
     i;
    // strip redundant leading global
    if (parts[0] === "MyProject") {
         parts = parts.slice(1);
    }
    for (i = 0; i < parts.length; i += 1) {
          // create a property if it doesn't exist
         if (typeof parent[parts[i]] === "undefined") {
             parent[parts[i]] = {};
         }


         parent = parent[parts[i]];
    }
return parent;
};


Now, we have a general purpose namespace function. How to use it? At top of your javascript file, declare the namespace using this function.

//in file MyProject/Models/Car.js
MyProject.ns('Models');
MyProject.Models.Car = {};

//in file MyProject/Modules/Products/Kindles/Wifi.js

MyProject.ns('Modules.Products.Kindles');
MyProject.Modules.Products.Kindles.Wifi = {};


Well, if we think the prefix MyProject.Modules.Products.Kindles is too long, we can simply do

var ns = MyProject.ns('Modules.Products.Kindles');
ns.Wifi = {};


In extjs, declaring a namespace is simple as Ext.ns('SomeNamespacesStringWithDotConnection'); 



Basically that is the whole idea of javascript namespace. Actually, JavaScript doesn’t have namespaces built into the language syntax, unlike java or PHP5.3. But the key is, javascript's object (function is object as well) can provide local scope, so just put everything into your own object, and you can achieve namespace feature.