简体   繁体   中英

Sorting Objects in a JavaScript Array by a Key Value

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?

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.

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.

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

var active_bugs = bugs.filter(function(bug) {
    return bug.status === "active";
});

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM