【问题标题】:Sorting array by 2 conditions in Javascript not working在Javascript中按2个条件对数组进行排序不起作用
【发布时间】:2018-04-30 09:58:02
【问题描述】:

我想按 id 和 name 对对象数组进行排序。首先它应该按 id 升序排序。然后它应该按名称升序排序。

排序功能

<script>
  $(document).ready(function() {
    var list = [{
      "id": "ts1",
      "name": "TS1"
    }, {
      "id": "ts10",
      "name": "TS10"
    }, {
      "id": "ts11",
      "name": "TS11"
    }, {
      "id": "ts12",
      "name": "TS12"
    }, {
      "id": "ts13",
      "name": "TS2"
    }, {
      "id": "ts13",
      "name": "TS1"
    }, {
      "id": "ts13",
      "name": "TS3"
    }, {
      "id": "ts14",
      "name": "TS14"
    }, {
      "id": "ts15",
      "name": "TS15"
    }, {
      "id": "ts16",
      "name": "TS16"
    }, {
      "id": "ts17",
      "name": "TS17"
    }, {
      "id": "ts18",
      "name": "TS18"
    }, {
      "id": "ts19",
      "name": "TS19"
    }, {
      "id": "ts2",
      "name": "TS2"
    }, {
      "id": "ts20",
      "name": "TS20"
    }, {
      "id": "ts21",
      "name": "TS21"
    }, {
      "id": "ts22",
      "name": "TS22"
    }, {
      "id": "ts3",
      "name": "TS3"
    }, {
      "id": "ts4",
      "name": "TS4"
    }, {
      "id": "ts5",
      "name": "TS5"
    }, {
      "id": "ts6",
      "name": "TS6"
    }, {
      "id": "ts7",
      "name": "TS7"
    }]

    list.sort(Sort_ID_Name);

    console.log(list);
  });

  function Sort_ID_Name(a, b) {
    try {
      var aID = a.id.toLowerCase();
      var bID = b.id.toLowerCase();
      var aName = a.name.toLowerCase();
      var bName = b.name.toLowerCase();
      return ((aID < bID) ? -1 : ((aID > bID) ? 1 : ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0))));
    } catch (err) {}
  }

</script>

目前排序列表显示如下:

{id: "ts1", name: "TS1"}
{id: "ts10", name: "TS10"}
{id: "ts11", name: "TS11"}
{id: "ts12", name: "TS12"}
{id: "ts13", name: "TS1"}
{id: "ts13", name: "TS2"}
{id: "ts13", name: "TS3"}
{id: "ts14", name: "TS14"}
{id: "ts15", name: "TS15"}
{id: "ts16", name: "TS16"}
....

理想状态是这样的

{id: "ts1", name: "TS1"}
{id: "ts2", name: "TS2"}
...
{id: "ts10", name: "TS10"}
{id: "ts11", name: "TS11"}
{id: "ts12", name: "TS12"}
{id: "ts13", name: "TS1"}
{id: "ts13", name: "TS2"}
{id: "ts13", name: "TS3"}
{id: "ts14", name: "TS14"}
{id: "ts15", name: "TS15"}
{id: "ts16", name: "TS16"}
....

该功能仅在列表很短时有效,但当列表很长时效果不佳。观看现场演示-https://jsfiddle.net/0xLd6sms/2/

【问题讨论】:

  • 与现在相比应该如何排序?
  • @zfrisch 请看现场演示。它应该按顺序排序,结果列表首先按 ID 排序,然后按名称排序
  • 我之所以这么问,是因为我在演示中并不清楚。 ID和名称都一样吗?无论如何,都应该在您的问题中而不是在外部进行概述。
  • @zfrisch 请看更新的演示,我更新了初始列表
  • 你能在这里发布更多你的代码吗?一些对象数组等?在这里发布代码不需要去其他地方回答。

标签: javascript jquery arrays sorting object


【解决方案1】:

您可以使用localeComapre() 指定numeric: true 选项使用自定义排序方法,它会智能地识别数字

var list = [{ "id": "ts1", "name": "TS1" }, { "id": "ts10", "name": "TS10" }, { "id": "ts11", "name": "TS11" }, { "id": "ts12", "name": "TS13" }, { "id": "ts13", "name": "TS2" }, { "id": "ts13", "name": "TS1" }, { "id": "ts13", "name": "TS3" }, { "id":"ts14", "name": "TS14" }, { "id": "ts15", "name": "TS15" }, { "id": "ts16", "name": "TS16" }, { "id": "ts17", "name": "TS17" }, { "id": "ts18", "name": "TS18" }, { "id": "ts19", "name": "TS19" }, { "id": "ts2", "name": "TS2" }, { "id": "ts20", "name":"TS20" }, { "id": "ts21", "name": "TS21" }, { "id": "ts22", "name": "TS22" }, { "id": "ts3", "name": "TS3" }, { "id": "ts4", "name": "TS4" }, { "id": "ts5", "name": "TS5" }, { "id": "ts6", "name": "TS6" }, { "id": "ts7", "name": "TS7" }];
list.sort((a,b) => a.id.localeCompare(b.id, undefined, {numeric: true}) || a.name.localeCompare(b.name, undefined, {numeric: true}));
console.log(list);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 我知道使用 `{numeric: true}' 的选项,但我没有看到也找不到关于未定义部分的文档。你能解释一下这到底是做什么的或指出我正确的方向吗?我知道这很重要,因为代码的工作是成败攸关的交易。
  • 除了@Matt 的问题,localeCompare 比较时会自动转小写吗?
  • @user8571142 它不会进行从上到下的转换。
  • 谢谢,所以如果我只想比较小写,那么我必须先将它们设置为小写
  • @HassanImam 你能在这里解释一下undefined的用法吗?
【解决方案2】:

您正在与字符串进行&gt;/&lt; 比较。这些适用于 unicode 点值,这很少是你想要的。改变这个:

  var aID = a.id.toLowerCase();
  var bID = b.id.toLowerCase();
  var aName = a.name.toLowerCase();
  var bName = b.name.toLowerCase();

到这里:

  var reg = /\d+/; // matches 1 or more number characters
  var aID = +a.id.match(reg)[0]; // unary + coerces to number
  var bID = +b.id.match(reg)[0];
  var aName = +a.name.match(reg)[0];
  var bName = +b.name.match(reg)[0];

现在您将根据字符串中的实际数值进行比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-02
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多