While (again) working on my node.js irc client, I needed to sort the array of nicks, prefixed with their respective modes, so I could list them correctly in my nickname list. This likely doesn't encompass all available modes, but more could easily be added. Hope someone else finds it useful.
This snippet first sorts them by their mode, then alphabetically.
Here's a jsfiddle, so you can see it in action: http://jsfiddle.net/jAdFx/2/
function sortNames(names) {
names.sort(function (a,b) {
var modes = '~&@%+';
var rex = new RegExp('^['+modes+']');
var nicks = [a.replace(rex,'').toLowerCase(), b.replace(rex,'').toLowerCase()];
var prefix = [];
if (rex.test(a)) prefix.push(modes.indexOf(a[0]));
else prefix.push(modes.length+1);
if (rex.test(b)) prefix.push(modes.indexOf(b[0]));
else prefix.push(modes.length+1);
if (prefix[0] < prefix[1]) return -1;
if (prefix[0] > prefix[1]) return 1;
if (nicks[0] > nicks[1]) return 1;
if (nicks[0] < nicks[1]) return -1;
return 0;
});
return names;
}
By using the 'indexOf' method for strings you could shorten your code quite a bit:
function sortNames(names) {
names.sort(function(name1, name2){
var nameA = [
"+%&@~".indexOf(name1[0]),
name1.toLowerCase().replace(/^[~@&%+]+/,"")
], nameB = [
"+%&@~".indexOf(name2[0]),
name2.toLowerCase().replace(/^[~@&%+]+/,"")
];
if (nameA[0] > nameB[0]) return -1;
if (nameA[0] < nameB[0]) return 1;
if (nameA[1] < nameB[1]) return -1;
if (nameA[1] > nameB[1]) return 1;
return 0
});
return names;
}
General Thoughts/Suggestions:
1: For something like the userlist, I'd create a custom object to keep track of not just nicks and prefixes but also user hosts, modes, etc, and have a sort method in the prototype
2: Instead of hardcoding prefixes, I'd suggest pulling them from the 005 raw numeric. That way your code will work on any compliant server
Nice, though I suggest moving the mode and regex var outside the sort function, and not using push(), since the values are statically placed:
It'd be more efficient/optimized to just hard code the array-filling instead of using push(). For small channels its not that noticable, but in large rooms of 1000+ users, the 'stalling spikes' while sorting the nicklist each time a user enters or changes nick would be quite noticable.
Not as of yet, but I'll toss one up once I have something a bit more functional. Until then, screenshots:
https://www.dropbox.com/s/mlyhzgxswh60j6w/nodeirc1.png
https://www.dropbox.com/s/m115361y1yq79k6/nodeirc2.png
https://www.dropbox.com/s/3w68lntv2mid8hp/nodeirc3.png
You can see the messages relayed from node in the first 2 shots. jQuery then emits events from this data. Most of the processing is done on the page.
I like it. I've changed my snippet. Yes, my client does indeed store user information along with the nicks, and modes are parsed from 005, but it was not applicable here.