【问题标题】:Scalable table sorting approach可扩展的表格排序方法
【发布时间】:2021-08-29 19:37:45
【问题描述】:

我想在反应中对每一列进行排序。我可以做到,但是强制代码,例如,如果我有这个数组并将其显示在一个 html 表中,我希望当我单击 id 时它按升序排序,当我单击名称时它按升序排序,然后再次单击它按降序排序,我想要名称和年龄相同。同时我想要一个箭头,如果该列在升序中,则向上查找,否则向下查找。

const USERS = [
  { id: 1, name: "Andy", age: 32 },
  { id: 2, name: "Bob", age: 30 },
  { id: 3, name: "Tom Hulk", age: 40 },
  { id: 4, name: "Tom Hank", age: 50 },
  { id: 5, name: "Audra", age: 30 },
  { id: 6, name: "Anna", age: 68 },
  { id: 7, name: "Tom", age: 34 },
  { id: 8, name: "Tom Riddle", age: 28 },
  { id: 9, name: "Bolo", age: 23 },
];

我可以做到的方式是这样的,但它很难看,也不实用。而且,当我更改箭头的排序状态时,它会更新所有箭头而不是我单击的列的箭头

  const sortBy = (k) => {
    if (k === "id") {
      if (sort) {
        const res = USERS.sort((a, b) => (a.id > b.id ? 1 : -1));
        setDataFilter(res);
        setSort(!sort);
        console.log(res);
      } else {
        const res = USERS.sort((a, b) => (a.id < b.id ? 1 : -1));
        setDataFilter(res);
        setSort(!sort);
        console.log(res);
      }
    } else if (k === "age") {
      if (sort) {
        const res = USERS.sort((a, b) => (a.age > b.age ? 1 : -1));
        setDataFilter(res);
        setSort(!sort);
        console.log(res);
      } else {
        const res = USERS.sort((a, b) => (a.age < b.agek ? 1 : -1));
        setDataFilter(res);
        setSort(!sort);
        console.log(res);
      }
    } else if (k === "name") {
      if (sort) {
        const res = USERS.sort((a, b) => a.name.localeCompare(b.name));
        setDataFilter(res);
        setSort(!sort);
        console.log(res);
      } else {
        const res = USERS.sort((a, b) => b.name.localeCompare(a.name));
        setDataFilter(res);
        setSort(!sort);
        console.log(res);
      }
    } else {
      console.log("hmm");
    }
  };

【问题讨论】:

  • 只需编写一个函数,该函数接受您要排序的属性和排序类型的参数。

标签: javascript html reactjs sorting html-table


【解决方案1】:

您可能希望在映射对象中对回调进行排序(按属性名称或按属性类型)。

此外,不要忘记利用 useMemo()/ useCallback() 钩子通过记忆排序输出来提高排序性能(这可能对大量项目有益):

const users = [
        { id: 1, name: "Andy", age: 32 },
        { id: 2, name: "Bob", age: 30 },
        { id: 3, name: "Tom Hulk", age: 40 },
        { id: 4, name: "Tom Hank", age: 50 },
        { id: 5, name: "Audra", age: 30 },
        { id: 6, name: "Anna", age: 68 },
        { id: 7, name: "Tom", age: 34 },
        { id: 8, name: "Tom Riddle", age: 28 },
        { id: 9, name: "Bolo", age: 23 },
      ],
      
      sortDirection = {
        'asc': 1,
        'desc': -1
      },
      
      numericSorter = propName => 
          sortOrder => 
            ({[propName]:a}, {[propName]:b}) => 
              (a-b)*sortDirection[sortOrder],
              
      stringicSorter = propName => 
          sortOrder => 
            ({[propName]:a}, {[propName]:b}) => 
              a.localeCompare(b)*sortDirection[sortOrder],
      
      sortMap = {
        id: numericSorter('id'),
        name: stringicSorter('name'),
        age: numericSorter('age')
      },
      
      sortUsers = (users, byProp, sortOrder) => 
        users.sort(sortMap[byProp](sortOrder))
        
console.log(sortUsers(users, 'name', 'desc'))
console.log(sortUsers(users, 'age', 'asc'))
.as-console-wrapper{min-height: 100%;}

【讨论】:

    【解决方案2】:

    试试下面的代码。它检查排序键值的类型并相应地选择排序方法。我重用了你的逻辑,让你变得简单。

    const USERS = [
      { id: 1, name: "Andy", age: 32 },
      { id: 2, name: "Bob", age: 30 },
      { id: 3, name: "Tom Hulk", age: 40 },
      { id: 4, name: "Tom Hank", age: 50 },
      { id: 5, name: "Audra", age: 30 },
      { id: 6, name: "Anna", age: 68 },
      { id: 7, name: "Tom", age: 34 },
      { id: 8, name: "Tom Riddle", age: 28 },
      { id: 9, name: "Bolo", age: 23 },
    ];
     
     
    const sortBy = (k, sort) => {
         var res;
         if( USERS[0] && (typeof USERS[0][k] == 'string')) {
              res = sort ? USERS.sort((a, b) => a[k].localeCompare(b[k])) : USERS.sort((a, b) => b[k].localeCompare(a[k]));
         } else {
             const f = sort ? 1 : -1;
             res = USERS.sort((a, b) => (a[k] > b[k] ? f : -f));
         }
         // setDataFilter(res);
         // setSort(!sort);
         console.log(res);
    }
     
    sortBy('name', 1);
    sortBy('age', 1);
    sortBy('name', 0);
    sortBy('age', 0);
    

    【讨论】:

    • 从值推断类型可能会导致某些类似数字的字符串的意外结果,这种情况经常发生。 IE。对于id['1', '2', '3', '10', 21'] 按升序排序,您将得到['1', '10', '2', '21', '3']
    • 年份 ID 也可以是字符串。它通常取决于 api 将返回什么数据,并且在这种情况下解析的响应 json 不会是数字值作为字符串,我敢肯定。如果它的类型是字符串,那么“10”应该小于“2”。无论如何,这一切都取决于数据,因此可以修改代码。
    猜你喜欢
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多