【问题标题】:Sorting Objects in a JavaScript Array by a Key Value按键值对 JavaScript 数组中的对象进行排序
【发布时间】:2011-11-19 00:00:32
【问题描述】:

我可能想出了一个非常粗略的方法来完成这种事情,但我想我会问在场的许多专家。基本上,我有一个如下所示的数组:

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

基本上,该数组包含几个“错误”,每个错误都有一个 id、title、summary、status、project、area 和 hours 属性。这些错误中的每一个都将显示在我的 Web 应用程序上,但我允许用户选择如何对它们进行分组;按状态、项目或区域。根据他们从上面的选择框中选择的三个中的哪一个,我希望能够对所有错误进行排序,并按他们选择的任何类别对它们进行分组。然后,在显示它们时,为该类别的每个当前选项设置一个简单的标题。例如,如果他们要按状态排序,它会是这样的:

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"

我是否应该遍历整个错误数组,并根据要排序的类别,为该类别的每个可能选项创建一个新数组并向它们添加适当的错误?所以在上面的例子中,创建新数组var activeBugs = []var resolvedBugs = []?如果是这样,那么我的问题将是知道有哪些可能的选择。在创建这些新数组之前,我是否应该首先遍历整个 bugs 数组以查看所需组类别存在哪些可能的选项?

在不求助于其他 jQuery 插件的情况下,最好的方法是什么?

【问题讨论】:

  • 对此有一个数组方法-.sort()
  • 如果您实际上不需要对它们进行排序,而只是想按特定字段对它们进行分组,我根本不会对它们进行排序。您使用什么来呈现这些列表(即,这是否会导致您需要对数组进行排序或为每个排序属性构建单独的数组)?
  • 我想我可以用它来按某个类别对数组本身进行排序。从那里,我只需要在标题更改为不同选项时打印出来?
  • @Dave Ward:嗯,我使用 AJAX 调用来填充我想要分组显示的原始 bugs 数组。 servlet 本身访问数据库以获取错误信息。所以我想我可以在 AJAX 调用期间传递 groupBy 选项并将其添加到我的 SQL 语句的 GROUP BY 部分......
  • 这不是.sort() 的工作,您正在寻找.filter()。不幸的是,IE 支持不好(仅限 9),因此您可能希望也可能不希望使用它,具体取决于计划的用途。 编辑:忘记包含链接 - 如果您对 IE 解决方法感兴趣,可以找到 proper code at MDN

标签: javascript jquery arrays sorting key


【解决方案1】:

要详细说明我质疑是否需要排序/过滤的评论,你能在你的显示逻辑中做一些(非常粗略地)这样的事情吗?

$('#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);
  }
});

工作演示:http://jsfiddle.net/TTApQ/1/

这样就根本没有排序或过滤,你只需要遍历数组。

【讨论】:

    【解决方案2】:

    用户会得到所有错误的副本吗?还是您只发送前 100 个?

    • 如果您发送前 100 个,我建议您在服务器上创建 3 个数组,其中包含指向对象的指针,并且每个新错误都根据其位置插入。然后从请求的列表中发送。这应该很快,因为您只需提取信息。并且排序是在插入时进行的。 (所有“排序”都是在添加错误时完成的 - 这假设您查看信息的频率高于您编辑它的频率!)
    • 如果客户端拥有所有数据的副本,则只需在客户端上使用 javascript 对其进行重新排序。不应该花太多时间。这可以节省您的带宽,并假设您没有那么多错误,因此您可以一次显示所有错误。

    【讨论】:

    • 客户端对访问数据库的服务器进行 AJAX 调用。当错误返回给客户端时,我认为最好将整个错误列表存储在客户端,这样如果用户想更改他们希望将它们分组的类别,我就不必再打电话了到 servlet(然后是数据库)。是让客户端处理排序更好,还是每次参数更改时都必须调用并让数据库处理?
    • 好吧,这取决于你有多少错误。如果您使用数据库,我想您的错误比用户看到的要多得多。因此发送所有数据将浪费带宽。如果您有一些,并且普通用户会看到所有这些-然后将它们全部发送。 --还要考虑未来的增长\减少。但主要问题是“普通用户会看到所有的错误吗?(或至少 90% 的错误,其中一些被一次又一次地发送)
    • 嗯,数据库中充满了所有用户的错误,但我的查询只返回那些分配给指定用户或已经有数小时由所述用户登录的用户。大多数时候,这在 5 到 20 个错误之间(我还没有见过有更多错误的用户)。不过,如果某个特定用户有 300 个错误,我希望它以同样的方式工作。
    【解决方案3】:

    使用 array.sort 按状态对数组进行排序。遍历数组,记住上一次迭代的 .status 属性是什么。当它发生变化时,创建一个新的视觉表示。

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

    警告:最终你会希望你让数据库完成所有的排序/分组/分页/等等。

    【讨论】:

    • 我最初将它们与数据库进行分组(“排序”)。但是,如果用户决定更改错误分组的类别,我将不得不再次调用服务器和数据库以使它们正确排序。我想如果我可以在客户端处理分组,我就不必每次更改“分组依据”选择框时都调用数据库。
    【解决方案4】:

    这是我在评论中描述的使用.filter() 的示例:

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

    【讨论】:

      最近更新 更多