【问题标题】:Typescript sorting list by status (string value)按状态排序的打字稿列表(字符串值)
【发布时间】:2020-01-03 06:50:50
【问题描述】:

我需要按状态对项目列表进行排序,但我不确定应该采用哪种方法,是创建比较器还是某种排序技术? lodash 会在这里工作吗?

示例输入列表:

[
{id: 1, name: "name1", status: "Failed"},
{id: 2, name: "name2", status: "Success"},
{id: 3, name: "name3", status: "In progress"},
{id: 4, name: "name4", status: "Reserved"},
{id: 5, name: "name5", status: "Pending"}
]

以失败 -> 进行中 -> 保留 -> 待处理 -> 成功排序的示例排序列表(输出)

[
{id: 1, name: "name1", status: "Failed"},
{id: 3, name: "name3", status: "In progress"},
{id: 4, name: "name4", status: "Reserved"},
{id: 5, name: "name5", status: "Pending"}
{id: 2, name: "name2", status: "Success"},
]

我使用的堆栈是 Angular + Typescript。

编辑:列表有点大,通常大约 15k 行。

【问题讨论】:

  • 我认为 arr.sort((a, b) => (b.status > a.status)) 应该做的工作
  • 但这只是按字母顺序排序吗?我的意思是,如果出现一些新状态,可以说“Astatus”,我希望它位于列表的末尾。
  • 我会建议您将状态映射为数字,例如:“失败”=> 0、“在 porgress”=> 1。这样您就可以清楚地看到排序是否有效

标签: angular typescript lodash


【解决方案1】:

您可以根据其他数组中的值对数组进行排序:

let sortOrder = ['Failed', 'In progress', 'Reserved', 'Pending', 'Success'];
let array = [
    { id: 1, name: "name1", status: "Failed" },
    { id: 2, name: "name2", status: "Success" },
    { id: 3, name: "name3", status: "In progress" },
    { id: 4, name: "name4", status: "Reserved" },
    { id: 5, name: "name5", status: "Pending" }
];

array.sort((a, b) => {
    return sortOrder.indexOf(a.status) - sortOrder.indexOf(b.status);
});

console.log(array);

【讨论】:

  • 那...只是简单的 osom :) 谢谢!
【解决方案2】:

要按自定义顺序对数据进行排序,您可以先将项目分组,然后根据您的排序顺序,将它们添加到最终输出中。

试试这样:

  constructor() {
    var groupedData = this.groupBy(this.data, "status");
    var sortArrangement = ["Failed", "In progress", "Reserved", "Pending", "Success"]
    sortArrangement.forEach(item => {
      groupedData[item].forEach(x => {
        this.result.push(x)
      })
    })
    console.log(this.result)
  }

  groupBy(xs, key) {
    return xs.reduce(function(rv, x) {
      (rv[x[key]] = rv[x[key]] || []).push(x);
      return rv;
    }, {});
  }

Working Demo

注意:您也可以将此逻辑移动到管道中。

【讨论】:

    【解决方案3】:

    要按任意值排序,创建一个Map或者一个对象,给每个状态赋予数值权重,然后使用Array.sort()或者lodash的_.orderBy(),根据状态从map中获取权重:

    const arr = [{"id":1,"name":"name1","status":"Failed"},{"id":2,"name":"name2","status":"Success"},{"id":3,"name":"name3","status":"In progress"},{"id":4,"name":"name4","status":"Reserved"},{"id":5,"name":"name5","status":"Pending"}]
    
    const order = new Map([['Failed', 0], ['In progress', 1], ['Reserved', 2], ['Pending', 3], ['Success', 4]])
    
    const result = _.orderBy(arr, o => order.get(o.status))
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

    【讨论】:

      【解决方案4】:

      您可以使用sort() 进行排序,如下所示使用状态对数组进行排序。

      const data = [
        { id: 1, name: "name1", status: "Failed" },
        { id: 2, name: "name2", status: "Success" },
        { id: 3, name: "name3", status: "In progress" },
        { id: 4, name: "name4", status: "Reserved" },
        { id: 5, name: "name5", status: "Pending" }
      ]
      
      function sortBy(data: any): any {
        const order = ['Failed', 'In progress', 'Reserved', 'Pending', 'Success']
        var ordering: any = {};
        for (var i = 0; i < order.length; i++)
          ordering[order[i]] = i;
        var result = data.sort(function(a: any, b: any) {
          return (ordering[a.status] - ordering[b.status]) || a.status.localeCompare(b.status);
        });
        return result;
      }
      
      console.log(sortBy(data));
      

      查看示例https://repl.it/repls/KnowingRareNlp

      【讨论】:

      • 好吧,生成的输出是: [ { "id": 1, "name": "name1", "status": "Failed" }, { "id": 3, "name": “name3”,“status”:“进行中”},{“id”:5,“name”:“name5”,“status”:“待定”},{“id”:4,“name”:“ name4", "status": "Reserved" }, { "id": 2, "name": "name2", "status": "Success" } ] 当我需要在 Pending 之前保留
      猜你喜欢
      • 2021-03-22
      • 2022-01-20
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      • 2016-01-29
      • 2013-04-19
      • 1970-01-01
      • 2021-06-10
      相关资源
      最近更新 更多