【问题标题】:How to sort on multiple columns using JavaScript sort?如何使用 JavaScript 排序对多列进行排序?
【发布时间】:2020-06-02 16:54:38
【问题描述】:

我有以下数组需要根据搜索文本“John”进行排序。

  {id: 1, firstName: 'User', lastName: 'John', nickName: 'Smith'},
  {id: 2, firstName: 'Test', lastName: 'John', nickName: 'Andrew'},
  {id: 3, firstName: 'Test', lastName: 'Zch', nickName: 'John'},
  {id: 4, firstName: 'Test', lastName: 'Mason', nickName: 'John'},
  {id: 5, firstName: 'John', lastName: 'Doe'},


];

预期输出:

数组应首先使用 nickName(带有搜索文本)排序,然后是 lastName(带有搜索文本)。如果 nickName 不存在,那么它应该按照 ASC 排序顺序相对于 firstName(带有搜索文本)进行排序。 注意:它应该将搜索文本单词视为 'John'

这种排序类似于在您的手机联系人应用中使用排序进行搜索

[
  // sort with nickName as higher relevance considering search text as John
  {id: 4, firstName: 'Test', lastName: 'Mason', nickName: 'John'},
  {id: 3, firstName: 'Test', lastName: 'Zch', nickName: 'John'},
  // sort with lastName considering search text
  {id: 2, firstName: 'Test', lastName: 'John', nickName: 'Andrew'},
  {id: 1, firstName: 'User', lastName: 'John', nickName: 'Smith'},
  // sort  with firstName as nickName is null
  {id: 5, firstName: 'John', lastName: 'Doe'},



];

我试过 localeMethod

function sortByLocale(user1, user2) {
   var sortByNickName = user1.nickName.toLowerCase().localeCompare(user2.nickName.toLowerCase());
   var sortByLastName = user1.lastName.toLowerCase().localeCompare(user2.lastName.toLowerCase());

   return sortByNickName || sortByLastName;
}

但结果在排序时没有考虑搜索文本。 我可以看到的一种方法是创建三个不同的数组并对它们进行排序并组合这些排序的数组 任何帮助将不胜感激。

编辑:不考虑具有搜索文本值的不匹配对象

【问题讨论】:

  • 传递给sort的比较函数期望返回一个数字,而不是布尔值。
  • @Olian04, localeCompare 返回数字,所以在这种情况下一切都是正确的,但实际上我读了 3 次并没有得到他想要的排序方式 =)
  • @DmitryReutov 类似于它在联系人中的工作方式。如果您在搜索框中键入 John,那么它将显示所有 John 的名字和姓氏,并按 ASC 顺序排列。然后一旦用名字排序完成,那么它将显示所有约翰姓氏和名字的记录将按 ASC 顺序排列
  • @ShoaibChikate,是的,最后我得到并发布了解决方案,请检查...但没有过滤掉您在示例中提供的非搜索文本

标签: javascript arrays sorting custom-sort


【解决方案1】:

只需添加第一个按名称搜索

function checkSearch (value)  {
   return (value.nickName === 'John') * -3 ||
      (value.lastName === 'John') * -2 ||
      (value.firstName === 'John') * -1 ||
      0
}

function sortByLocale(user1, user2) {
   var sortBySearch = checkSearch(user1) - checkSearch(user2)

   var sortByNickName = (user1.nickName || '').toLowerCase().localeCompare((user2.nickName || '').toLowerCase());
   var sortByLastName = user1.lastName.toLowerCase().localeCompare(user2.lastName.toLowerCase());

   return sortBySearch || sortByNickName || sortByLastName;
}

【讨论】:

  • 太棒了。感谢您提供完美干净的解决方案
【解决方案2】:

你可以对想要的顺序进行两次迭代

  1. 一个用于想要的字符串
  2. 其余的顺序

var data = [{ id: 1, firstName: 'User', lastName: 'John', nickName: 'Smith' },
  { id: 2, firstName: 'Test', lastName: 'John', nickName: 'Andrew' },
  { id: 3, firstName: 'Test', lastName: 'Zch', nickName: 'John' },
  { id: 4, firstName: 'Test', lastName: 'Mason', nickName: 'John' },
  { id: 5, firstName: 'John', lastName: 'Doe' }
],
    search = 'john',
    check = (s => (o, k) => (o[k] || '').toLowerCase() === search)(search),
    keys = ['nickName', 'lastName', 'firstName'];

data.sort((a, b) => {
    const
        fns = [
            k => d = check(b, k) - check(a, k),
            k => d = (a[k] || '').localeCompare(b[k] || '')
        ];
    let d = 0;
    fns.some(fn => keys.some(fn));
    return d;
});

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 支持解决方案。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多