根据多个属性条件对对象数组排序

问题描述 投票:0回答:1

我正在尝试重构一些真正的笨蛋和过于复杂的代码,这些代码试图对一组对象进行排序。数组如下所示:

[
  {
    "status": "CANCELLED",
    "createdDate": "2020-02-19T22:22:43Z",
    "dueDate": "2020-02-20T06:00:00Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-16T22:01:35Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-02-19T22:24:28Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-27T23:30:08Z"
  },
  {
    "status": "COMPLETE",
    "createdDate": "2019-08-27T04:53:46Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-15T08:39:24Z",
    "dueDate": "2020-01-16T08:38:00Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-16T22:02:43Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-16T04:48:56Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-03-31T04:07:17Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-27T23:27:25Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-03-12T03:28:24Z"
  },
  {
    "status": "COMPLETE",
    "createdDate": "2019-04-22T23:08:29Z",
    "dueDate": "2019-04-23T07:00:00Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-16T21:49:11Z",
    "dueDate": "2020-01-17T06:00:00Z"
  },
  {
    "status": "CANCELLED",
    "createdDate": "2019-04-22T23:13:22Z",
    "dueDate": "2019-04-23T07:00:00Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-21T23:36:43Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-06T02:51:48Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-16T03:46:44Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-16T03:46:11Z"
  },
  {
    "status": "OPEN",
    "createdDate": "2020-01-28T02:42:15Z"
  }
]

条件按优先顺序如下:

  • 有到期日期的项目在顶部
  • 他们应该遵循以下“状态”顺序:“打开”,“完成”,“取消”
  • 它们应按'createdDate'降序排列,所以最新的物品在顶部

我一直在使用Array.prototype.sort函数来学习它的工作原理,但有时还不知道我在做什么。但是,我能够满足第一个和第二个条件,但不能满足第三个条件。

我的工作代码是:

this.items = this.items.sort((a, b) => {
    let rv = 0;
    if (b.status === 'OPEN' || a.status === 'CANCELLED') {
        rv = 1;
    }
    if (a.dueDate && a.status === 'OPEN') {
        rv = -1;
    }
    return rv;
});

但是当我尝试满足第三个条件时,其他条件将不再受尊重。它看起来像:

if(new Date(a.createdDate).getTime() < new Date(b.createdDate).getTime()) {
  // return something
}

我认为在同一个排序函数中可能无法实现,因此必须将其拆分为几个,或者我需要比我聪明得多的人。

感谢您的帮助

javascript arrays
1个回答
0
投票

通过多个条件排序的方式是用第二个条件的返回值替换第一个条件的0情况,并用第三个条件替换第二个条件的0情况。如果您认为这是“使用下一个条件,则它们在第一个条件的基础上进行了相同的排序”,这在逻辑上是遵循的。

const statusValues = {
  OPEN: 0,
  COMPLETED: 1,
  CANCELLED: 2
};

this.items = this.items.sort((a, b) => {
  if (a.dueDate && !b.dueDate) return -1;
  if (b.dueDate && !a.dueDate) return 1;

  const statusDiff = statusValues[a.status] - statusValues[b.status];
  if (statusDiff !== 0) return statusDiff;

  return a.createdDate.localeCompare(b.createdDate);
});
© www.soinside.com 2019 - 2024. All rights reserved.