Sort Array of IRC Nicks With Modes

By PennyBreed on Apr 07, 2014

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;
}

Comments

Sign in to comment.
Hawkee   -  Oct 13, 2014

How is your IRC client coming along? Would be interested to see a status update.

 Respond  
SReject   -  Apr 10, 2014

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

PennyBreed  -  Apr 10, 2014

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.

SReject  -  Apr 10, 2014

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.

Sign in to comment

Vegito   -  Apr 09, 2014

names = ['~billy','~PennyBreed','~someHelper','+SomeDude','SomeGal','~Abby'];

When I run it, I get following result:

["~Abby","~PennyBreed","~billy","~someHelper","+SomeDude","SomeGal"]

Uppercase goes before lowercase.
idk if that is suppose to happen.

PennyBreed  -  Apr 09, 2014

Indeed. Switching them toLowerCase() before comparing them fixes this. Snippet updated.

Sign in to comment

Hawkee   -  Apr 07, 2014

A node.js IRC client. Interesting idea. What sort of UI will you be building?

PennyBreed  -  Apr 07, 2014

It's browser-based (node sends the irc events to the browser via web socket). I'm using Total.js as my framework and Bootstrap for responsive styling.

Hawkee  -  Apr 07, 2014

Very cool, do you have a WIP demo online? I'd love to see it

PennyBreed  -  Apr 07, 2014

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.

ProIcons  -  Apr 08, 2014

Seems Interesting. Though there's an error

        if (keyA < keyB) return 1;
        if (keyA > keyB) return -1;

->

        if (keyA > keyB) return 1;
        if (keyA < keyB) return -1;
PennyBreed  -  Apr 08, 2014

Good eye... Fixed the snippet and the fiddle.

ProIcons  -  Apr 08, 2014

In fact, it is not sorting names without prefix, you'll need also to change these lines:

default: mA=0; break;
//->
default: mA=0; var keyA=a; break;

default: mB=0; break;
//->
default: mB=0; var keyB=b; break;
PennyBreed  -  Apr 08, 2014

Can't believe I didn't notice that O.o ... all fixed up now.

Sign in to comment

Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.