I may have come up with an incredibly crude way to get this sort of thing accomplished, but I figured that I'd ask the many experts present here at SO. Basically, I have an array that looks something like the following:

var bugs = [
    {
        id: "197526",
        title: "Updating Lighthouse",
        summary: "Enhancing the UI of Lighthouse",
        status: "Active",
        project: "Lighthouse",
        area: "Internal Web Applications",
        hours: 19
    },
    {
        id: "190328",
        title: "Adding Login Authentication to Lighthouse",
        summary: "Create a login authentication process for Lighthouse",
        status: "Active",
        project: "Lighthouse",
        area: "Administration",
        hours: 12
    },
    ...
    {
        id: "187562",
        title: "Create a Maintenance Page",
        summary: "Create a maintenance page to be displayed with the company site is down",
        status: "Resolved",
        project: "Other",
        area: "Internal Web Projects",
        hours: 4
    },
];

Basically, the array holds several "bugs," each with an id, title, summary, status, project, area, and hours property. Each of these bugs are going to be displayed on my web application, but I allow the user to select how they will be grouped; either by status, project, or area. Depending upon which of the three they select from a select box above, I want to be able to sort through all of the bugs and group them by whichever category they chose. Then, when it comes to displaying them, have a simple header for each present option for that category. For example, if they were to sort by status, it would be something like:

Group By: Status

Active
------
Bug with status: "active"
Bug with status: "active"
Bug with status: "active"

Resolved
--------
Bug with status: "resolved"
Bug with status: "resolved"

Should I iterate through the entire array of bugs and, based on the category to sort by, simply create a new array for each possible option of that category and add the appropriate bugs to them? So in the case above, create new arrays var activeBugs = [] and var resolvedBugs = []? If so, my problem would then be knowing what possible options there are. Should I then first iterate through the entire bugs array to see what possible options are present for the desire group category before creating these new arrays?

What's the best way to do this without resorting to other jQuery plugins?

share|improve this question
There is an array method for this - .sort() – Šime Vidas Nov 19 '11 at 0:09
If you don't need to actually sort them, but just want to group them by a particular field, I wouldn't sort them at all. What are you using to render these lists (i.e. is that leading to your need to sort the array or build separate arrays per sort-property)? – Dave Ward Nov 19 '11 at 0:16
I suppose I can use that to sort them all in the array itself by a certain category. From there, I just need to print out the headers whenever they change to a different option? – Kris Schouw Nov 19 '11 at 0:16
@Dave Ward: Well, I use an AJAX call to fill the original bugs array that I want grouped for displaying. The servlet itself accesses a database in order to get the bug information to begin with. So I suppose I can pass the groupBy option during the AJAX call and add it to the GROUP BY part of my SQL statement... – Kris Schouw Nov 19 '11 at 0:18
This isn't a job for .sort(), you're looking for .filter(). Unfortunately the IE support is not good (9 only), so you may or may not want to use it depending on the planned use. Edit: Forgot to include a link - if you're interested in having the IE work-around, you can find the proper code at MDN – Alec Ananian Nov 19 '11 at 0:20
show 1 more comment

4 Answers

up vote 0 down vote accepted

To elaborate on my comment questioning the need to sort/filter at all, can you do something (very roughly) like this in your display logic?

$('#SortOrder').live('change', function() {
  var groupby = $(this).val();

  $('#Bugs').empty();

  for (var i = 0; i < bugs.length; i++) {
    if (!document.getElementById(bugs[i][groupby])) {
        $('<h3>', { text: bugs[i][groupby] }).appendTo('#Bugs');

        $('<ul>', {
            id: bugs[i][groupby]
        }).appendTo('#Bugs');
    }

    var $li = $('<li>', {
        text: bugs[i].title
    });

    $('#Bugs').find('#' + bugs[i][groupby]).append($li);
  }
});

Working demo: http://jsfiddle.net/TTApQ/1/

That way there's no sorting or filtering at all, and you only need to make one pass over the array.

share|improve this answer
I will give that a try, thank you. – Kris Schouw Nov 30 '11 at 23:07

Will the user have a copy off all the bugs? or do you just send, lets say, the first 100?

  • If you send the first 100, the I suggest you to make 3 arrays on the server, which hold pointers to the objects, and every new bug is inserted according to its position. and then just send from the list that was requested. that should be fast because you just pull information. and the sorting is at insertion time. (all 'sorting' is done when the bug is added - this assumes that you view info more often that you edit it!)
  • If the client holds a copy of all the data, then just re-sort it on the client with javascript. shouldn't take too much time. this saves you bandwidth, and assumes you don't have that much bugs so you can show all of them at once.
share|improve this answer
The client makes an AJAX call to the server that accesses the database. When the bugs are returned to the client, I thought it best to store the entire list of bugs on the client-side so that if the user thought to change which category they wanted them grouped by, I wouldn't have to make another call to the servlet (and in-turn the database). Is it better to let the client deal with the sorting, or having to make a call each time the parameter changes and have the database deal with it? – Kris Schouw Nov 19 '11 at 0:33
well, depends on how much bugs you have. if you use a database, i guess that you have much more bugs than a user will see. so sending all data would be a waste of bandwidth. if you have a few, and an average user will see all of them - then send them all. --also consider future growth\reduction. but the main question is "will the average user see all the bugs? (or at least 90% of them with some of them being sent again and again) – Martin Nov 19 '11 at 12:16
Well, the database is full of bugs for all users, but my query only returns those either assigned to the specified user or those that already have hours logged on them by said user. Most of the time, this is between 5-20 bugs (I haven't seen a user with more than that, yet). Still, if a particular user had 300 bugs, I'd want it to work the same way. – Kris Schouw Dec 1 '11 at 22:55

Sort the array by status using array.sort. Iterate through the array remembering what the previous iteration's .status property was. When it changes, create a new visual representation.

bugs.sort(mySortFunc);

var lastStatus = '';
for (var i=0, b; b = bugs[i]; i++) {
  if (b.status != lastStatus) {
    //output a header for the new status b.status
    document.write(b.status + '<br>----<br>');
    lastStatus = b.status;
  }
  // output the bug
  document.write(b.title + '<br>');
}

Warning: Eventually you'll wish you had let the database do all the sorting/grouping/paging/etc.

share|improve this answer
I was grouping ("ordering") them with the database originally. However, if the user decided to change the category in which the bugs were grouped, I'd have to make another call to the server and to the database to get them ordered properly. I thought that if I can deal with the grouping on the client-side, I wouldn't have to make a call to the database each time they changed the "Group By" select box. – Kris Schouw Nov 19 '11 at 0:35

Here's an example using .filter() as I described in my comment:

var active_bugs = bugs.filter(function(bug) {
    return bug.status === "active";
});
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.