Thursday, October 29, 2009

Two dimensional Array (Table Array) Multiple column sorting using JavaScript

Here is a JavaScript implementation for multi-column ascending sort on a table array.

Below is the code for this.
var tempArray = new Array();
//main function
function do2DArraySort(arrayToBeSorted, sortColumnArray)
{
if (arrayToBeSorted == "undefined" || arrayToBeSorted == "null") return arrayToBeSorted;
if (arrayToBeSorted.length == 0) return arrayToBeSorted;
if (sortColumnArray.length == 0) return arrayToBeSorted;
tempArray = arrayToBeSorted; 
var totalLength = sortColumnArray.length; 
for(var m = 0; m < totalLength; m++)
{
if (m == 0)
{   
doBubbleSort(tempArray, tempArray.length, sortColumnArray[m]);         
}
else
{     
doMultipleSort(tempArray, sortColumnArray[m], sortColumnArray[m-1]);
}
} 
return tempArray;
}

//basic bubble sort implementation
function doBubbleSort(arrayName, length, element) 
{
for (var i = 0; i < (length-1); i++)
{
for (var j = i+1; j < length; j++)            
{
if (arrayName[j][element] < arrayName[i][element]) 
{
var dummy = arrayName[i];
arrayName[i] = arrayName[j];
arrayName[j] = dummy;
}
}
}  
}

//appends an array content to the original array
function addToArray(originalArray, addArray)
{
if (addArray.length != 0)
{
var curLength = 0;
curLength = originalArray.length;
var maxLength = 0;
maxLength = curLength + addArray.length;  
var itrerateArray = 0;
for (var r = curLength; r < maxLength; r++)
{   
originalArray[r] = addArray[itrerateArray];
itrerateArray++;
}
}
}

//check if a value exists in a single dimensional array
function checkIfExists(arrayToSearch, valueToSearch)
{
if (arrayToSearch == "undefined" || arrayToSearch == "null") return false;
if (arrayToSearch.length == 0) return false;
for (var k = 0; k < arrayToSearch.length; k++)
{
if (arrayToSearch[k] == valueToSearch)
return true;
}
return false;
}

//sorts an 2D array based on the distinct values of the previous column
function doMultipleSort(sortedArray, currentCol, prevCol)
{
var resultArray = new Array(); 
var newdistinctValuesArray = new Array();
//finding distinct previous column values 
for (var n = 0; n < sortedArray.length; n++)
{ 
if (checkIfExists(newdistinctValuesArray, sortedArray[n][prevCol]) == false)
newdistinctValuesArray.push(sortedArray[n][prevCol]);
}  
var recCursor = 0;
var newTempArray = new Array(); var toStoreArray = 0; 
//for each of the distinct values
for (var pp = 0; pp < newdistinctValuesArray.length; pp++)
{
toStoreArray = 0;
newTempArray = new Array();  
//find the rows with the same previous column value
for (var qq = recCursor; qq < sortedArray.length; qq++)
{
if (sortedArray[qq][prevCol] != newdistinctValuesArray[pp]) break;
newTempArray[toStoreArray] = sortedArray[qq];
toStoreArray++; recCursor++;
}
//sort the row based on the current column   
doBubbleSort(newTempArray, newTempArray.length, currentCol);
//append it to the result array
addToArray(resultArray, newTempArray);
}
tempArray = resultArray;
}
The above code can be stored as TableArrayMultipleSort.js for our example usage shown below:
<html>
<head>
<title>Invoking Multiple Array Sort</title>
<script language="javascript" src="TableArrayMultipleSort.js" type="text/javascript"></script>
</head>
<body>
<script language="javascript" type="text/javascript">
function createSampleArray()
{ 
var myArr = new Array( 
new Array("Ashley","13","Male","Texas"),
new Array("Smith", "32", "Male","Colorado"),
new Array("Jane", "21", "Female","South Carolina"),
new Array("Anna", "12", "Female","Maryland"),
new Array("Ashley","13","Male","Delaware"),
new Array("Ashley","46","Male","Newyork")
); 
return myArr;
}
function showDataByRow(arrayToBeShown)
{
for(var a=0;a<arrayToBeShown.length;a++)
{
document.write(arrayToBeShown[a]+"<br>");
}
}
document.write("<b>Original Array: (Input)</b>" + "<br><br>");
showDataByRow(createSampleArray());
document.write("<br><br><br>");
var sortColumnArray = new Array('0','1','3'); 

document.write("<b>Sorted Array: (Output)</b><br>Order: First column, then by second column and then by Last Column" + "<br><br>");
showDataByRow(do2DArraySort(createSampleArray(),sortColumnArray));
</script>
</body>
</html>
When the above code is executed, this will show the input table array and output table array as shown below. Original Array: (Input)
Ashley,13,Male,Texas
Smith,32,Male,Colorado
Jane,21,Female,South Carolina
Anna,12,Female,Maryland
Ashley,13,Male,Delaware
Ashley,46,Male,Newyork
Sorted Array: (Output) Order: First column, then by second column and then by Last Column
Anna,12,Female,Maryland
Ashley,13,Male,Delaware
Ashley,13,Male,Texas
Ashley,46,Male,Newyork
Jane,21,Female,South Carolina
Smith,32,Male,Colorado
Enhancements: 1. The code can be enhanced to accomodate sort order for each of the sort columns by having a seperate array to specify that.
2. It can be relooked for performance improvements and enhanced variable handling.
3. There are few issues related to null/empty-value, if it exists in any of the columns being sorted.


Note: The objective of this article is to assist in learning the Javascript array concepts and it's usage. This code is not intended to be used for production purposes as it is not written with that aspect in mind. So, if you want to use it, use it at your own risk.

Sunday, October 25, 2009

Large Grasshopper

This big one was just sitting there having all the food that he can; finished a major portion of the plant's leaves. It's pretty colorful and is around 9.5 cm long.

If someone, who study these, is looking for a nice snap of this one, here it is. Please comment on the scientific name so that others can find this.



















































Wednesday, October 21, 2009

Threading in .net - for Beginners


Method 1: Using ThreadPool.QueueUserWorkItem

There may be scenarios, in which you want to have an asynchronous operation to be performed without the need of a handle on the function being called. For example, this can be an audit log or a process log operation which can be a background process while your main application performs the important operations. There is a simple single line code to achieve this using ThreadPool.QueueUserWorkItem call. Typical usage is as follows.


private void button1_Click(object sender, EventArgs e)
{
string argument = "Process started";
ThreadPool.QueueUserWorkItem(new WaitCallback(WriteLog), input);
}

private void WriteLog(object o)
{
string argument = o as string;
// Your code to log the argument
}

In this method:
1. With a single line code, you are getting the basic benefits of threading without having to worry about creating, managing and terminating a threaded operation.
2. QueueUserWorkItem call is in control of .net runtime. You will not be able to control the time at which it gets executed.
3. You cannot control the state and priority of the function being executed.

Method 2. Using ThreadStart, ParameterizedThreadStart and Thread

Below is another method that will give more control on your asynchronous operation.

a) Without having a Parameter

Class level decleration


private Thread t = null;


This can be used for later tracking of the thread being executed.

private void button2_Click(object sender, EventArgs e)
{
ThreadStart ts = new ThreadStart(WriteStartLog);
t = new Thread(ts);
t.IsBackground = true;
t.Priority = ThreadPriority.Normal;
t.Start();
}

private void WriteStartLog()
{
// Your code to log the process start
}


To track the thread, the thread object can be used. A sample usage is provided below:

private void button3_Click(object sender, EventArgs e)
{
if (t != null)
{
if (t.IsAlive)
t.Abort();
}
}


b) Passing parameters using ParameterizedThreadStart

When parameters are to be passed to the invoked method, this can be done using ParameterizedThreadStart using the medium as objects.



private void button2_Click(object sender, EventArgs e)
{
ParameterizedThreadStart pts = new ParameterizedThreadStart(WriteLog);
t = new Thread(pts);
t.IsBackground = true;
t.Priority = ThreadPriority.Normal;
t.Start("Process started");
}


private void WriteLog(object o)
{
string argument = o as string;
// Your code to log the argument
}

Now that we have covered the basic skeleton of our article, let’s see the other important aspects of threading.

Handling ThreadAbortException

There might be a need to abort the thread being executed at any instant of time. This can happen due to the user cancellation of the process or any other action like the primary thread being closed due to a various reason. At these scenarios (even when there is no need), it is mandatory to have a ThreadAbortException to be handled in the method which is being called. This can be as follows:



private void WriteLog()
{
try
{
// Your code to log the argument
}
catch (ThreadAbortException tae)
{
//handles the thread abort exception
//code to cleanup - let know the user that thread got cancelled, if necessary.
}
catch (Exception e)
{
//handle other exceptions
}
}


Communicating between main and background thread.

Consider, this scenario:
You are having a background thread to create thumbnails for pictures in a folder. For each thumbnail being created, you have to draw it on the form. That is, to communicate from the background thread to the parent thread with the output from the background thread. This is pretty simple using delegates. Here it is how it’s done.

Class level declarations:


private delegate void addPictureBox2Main_Delegate(PictureBox pbb);
private Thread t = null;



private void button2_Click(object sender, EventArgs e)
{
ThreadStart ts = new ThreadStart(LoadImageThumbNails);
t = new Thread(ts);
t.IsBackground = true;
t.Priority = ThreadPriority.Normal;
t.Start();
}

private void LoadImageThumbNails()
{
try
{
//for each of the thumbnails being created
//generate picturebox with thumbnail here
PictureBox pb = //function to load thumbnail
this.Invoke(new addPictureBox2Main_Delegate(addPictureBox2Main), new Object[] { pb });
}
catch (ThreadAbortException tae)
{
//handles the thread abort exception
//code to cleanup - let know the user that thread got cancelled, if necessary.
}
catch (Exception e)
{
//hanlde other exceptions
}
}


private void addPictureBox2Main(PictureBox pb)
{
//add the picture box pb to the parent control as needed
}


** Code samples are in C#**

Note: This article only covers the basic aspect of threading and it aims to help beginners understand the threading concepts. There is more to it. So, keep learning.