Java/JavaScript tips for removing list elements when iterating list

This is Java and JavaScript tips for same topic, removing list elements when iterating list.

In Java, we will use List as an example, as it is uncommon to remove element from an Array. In Javascript we will use Array as an example, as only Array is supported in JavaScript.

Introduction

To remove an element from a Java List, you will do

List someList = new ArrayList();
someList.add("two");
someList.add("one");
someList.add("three");
someList.remove(1); // to remove by index
someList.remove("one); // to remove by element value
System.out.println(someList);

To remove an element from a JavaScript Array, you will do

var someArray = ["two", "one", "three"];
someArray.splice(1, 1); // to remove by index
console.log(someArray);

What if you want to remove an element from a List or Array when you iterating the List, you want to remove it based on some conditions?

In Java, you may do

List someList = new ArrayList();
someList.add("two");
someList.add("one");
someList.add("three");

for(String item : someList) {
  if(item.equals("one")) {
    someList.remove(item); // #1
  }
  else if(item.equals("three")) {
    someList.remove(item); // #2
  }
}

Unfortunately, by doing this, you will get exception thrown.

By executing line #1, “one” is removed from someList, and next if you still continue the for loop, you will get exception as someList is modified, affecting the for loop execution.

The best way to remove item from a Java list is to use Iterator

List someList = new ArrayList();
someList.add("two");
someList.add("one");
someList.add("three");

Iterator it = someList.iterator();
while(it.hasNext()) {
  String item = it.next();
  if(item.equals("one")) {
    it.remove();
  }
  else if(item.equals("three")) {
    it.remove();
  }
}

System.out.println("Latest someList: " + someList);

This is the safe way to remove items from List when you will still continue iterating over the someList.

In JavaScript, you may do

var someArray = ["two", "one", "three"];
for(var i = 0; i < someArray.length; i++) {
  if(someArray[i] == "one") {
    someArray.splice(i, 1); // #1
  }
  else if(someArray[i] == "three") {
    someArray.splice(i, 1); // #2
  }
}

Unfortunately, by doing this, you will get exception thrown.

By executing line #1, "one" is removed from someArray, and next if you still continue the for loop, you will get exception as someArray is modified, affecting the for loop execution.

The best way to remove item from a JavaScript array is to iterate the Array from last.

var someArray = ["two", "one", "three"];
for(var i = someArray.length - 1; i >= 0; i--) {
  if(someArray[i] == "one") {
    someArray.splice(i, 1); // #1
  }
  else if(someArray[i] == "three") {
    someArray.splice(i, 1); // #2
  }
}

This is the safe way to remove items from JavaScript Array.

Why this works? You may think same thing also applies to Java right? Yes you are right. How this works? Leave it for your back home reading.

JavaScript universal http request method – frequest

I wrote some universal JavaScript method for my apps, across Node.JS and Titanium Mobile, Freeswitch, jQuery. Here introduces a very simple but useful method, http request.

We all doing HTTP request on our apps. Make a request via HTTP and get back the response. I designed an API that I can use the same method signature when I am developing apps for Node.JS and Titanium Mobile. Node.JS is a server side program, and Titanium Mobile is a framework compile to Native iOS code. Freeswitch is an open source SIP Media Server, supports JavaScripts to create IVR apps. jQuery is a web based client framework. These platforms had different underlying native libraries to do HTTP request. I just want to design a very simple API that can wrap up these platforms, then I can share code easily across these platform.

The client code I can do:

frequest({
    url : 'http://somewebsite.com',
    callback : function(data) {
        console.log(data);
    }
});

The code for Node.JS:

frequest : function(args) {
		var http = require('http');
		
		try {
			var options = {};
		
			if(args.options) {
				
				options = args.options;
				
			}
			 
			if(args.url) {
				if(args.url.indexOf('http') == -1) return;
				var b = require('url').parse(args.url);
				
				// resolve host name
				if(b.hostname) {
					options.host = b.hostname;
				}
				
				// resolve port
				if(!b.port) {
					b.port = 80;
				}
				
				if(b.port) {
					options.port = b.port;
				}
				
				// resolve web path
				if(b.pathname) {
					options.path = b.pathname;
					
					if(b.search) {
						options.path += b.search;
					}
				}
					
			}
			
			if(args.headers) {
				options.headers = args.headers;
			}
		    
		    var request = http.get(options);
		
			if(args.callback || args.callbackJSON) {
				request.addListener('response', function(response){
				    var data = '';
				
				    response.addListener('data', function(chunk){ 
				        data += chunk; 
				    });
				    response.addListener('end', function(){
				        
				        // prepare data for callback
				        
				        if(data != '') {
				        	if(args.callback) {
					        	args.callback(data);
					        }
					        
					        if(args.callbackJSON) {
					        	try {
					        		var json = JSON.parse(data);
					        		args.callbackJSON(json);	
					        	
					        	} catch (e) {
					        		console.log(e);
					        	}
					        }
				        }
				        
				    });
				});
			}
		} catch (e) {
			console.log(e);
		}
		
		
	
	}

The code for Titanium Mobile:

var frequest = function(args) {
	
	
	var xhr = Ti.Network.createHTTPClient();
	xhr.onload = function() {
		var res = this.responseText;
		
		if(args.callback) {
			args.callback(res);
		}
		
		if(args.callbackJSON) {
			args.callbackJSON(JSON.parse(res));
		}
	};
	
	xhr.onerror = function(e) {
		// detect message
		var errortitle = 'Connection Failure Error';
		var errormsg = ''; // define some suggested network failure message
		if(e.error && e.error.indexOf('A connection failure occurred')) {
			errormsg = 'A connection failure occurred';
		}
		if(args.errorCallback) {
			args.errorCallback({
				e : e,
				errormsg : errormsg
			});
		} else {
			Ti.UI.createAlertDialog({
				title : errortitle,
				message : errormsg
			}).show();
		}
	}
	if(args.timeout) {
		xhr.timeout = args.timeout;
	}
	if(args.progressCallback) {
		xhr.onsendstream = function(e) {
			args.progressCallback(e.progress);
		}
	}
	
	var method = args.method || 'GET';
	xhr.open(method, args.url);
	if(args.headers) {
		for(var k in args.headers) {
			var v = args.headers[k];
			xhr.setRequestHeader(k,v);
		}
	}
	var params = args.params || null;
	if(params != null) 
		xhr.send(params);
	else
		xhr.send();
};

The code for Freeswitch:

frequest : function(args) {
		var result = fetchUrl(args.url);
		if(args.callback) {
			args.callback(result);
		}
	}

The code for jQuery:

var frequest = function(args) {
    $.ajax({
      url : args.url,
      success : args.callback
    });
};

Feel free to share your code for related frequest implementation.

Video for using Node.js for Everything

This is another talks video by Charlie Key, the CEO at Modulus, he share with us how Node.JS succeed for development nearly every aspects for a startup where load balance, performance, usability, enterprise class are considered.

He introduced and demo some new tools like Node-inspector, which is a web based inspector to inspect/debug Node code. The debugger interface is nearly same as the native Google Chrome/Safari Developer tools which developed for inspect client web JavaScript and this web based inspector is a completely rewrite mimic the look and feel and features of the native inspector just using JavaScript, and quite powerful, and quite interesting.

Meanwhile he introduced Modulus, an enterprise class Node.JS + MongoDB cloud platform, have a look.

[youtube]wsuygCu_oPY,desc=Using Node JS for Everything[/youtube]

Video for JavaScript & Our Obsession with Speed

This is a talks by Brian Lonsdorf, the CTO of Loop/Recur, who at least last 5 years stuck in JavaScript development, give a talks why we should not always comes to performance in an early stage, and he talks about the benefits of declarative over imperative way.

I spent my time to watch this video and I found useful so I share here to you. Now is Singapore Time 1:15am and I watched this video when I reached home from works just now, but unfortunately I slept in front of computer after this video nearly finished… But I should blog this video before sleep.

[youtube]0wgDGTgOPds,desc=JavaScript Our Obsession with Speed[/youtube]