【问题标题】:Combine two array and sort them by the dateTime field合并两个数组并按 dateTime 字段排序
【发布时间】:2019-01-15 04:24:23
【问题描述】:

我有两个排序数组,并将它们组合成一个新的 listC。

listA = [
  {id:"1234435", name:"apple", dateTime_ISO:"2019-01-15 17:27:30"},
  {id:"1234435", name:"orange", dateTime_ISO:"2019-01-15 10:25:30"},
  {id:"1234435", name:"banana", dateTime_ISO:"2019-01-15 10:25:02"},
  {id:"1234435", name:"pear", dateTime_ISO:"2019-01-15 07:21:52"},
  {id:"1234435", name:"lemon", dateTime_ISO:"2019-01-15 07:22:24"},
]

listB = [
  {id:"1234435", name:"bread", dateTime:"2019-01-15 17:27:34"},
  {id:"1234435", name:"rice", dateTime:"2019-01-15 09:25:30"},
  {id:"1234435", name:"noodle", dateTime:"2019-01-15 07:25:02"},
  {id:"1234435", name:"pie", dateTime:"2019-01-15 07:06:52"},
  {id:"1234435", name:"cake", dateTime:"2019-01-15 06:22:24"},
]

listC = this.listA.concat(this.listB)

如何根据 dateTime 对 listC 进行排序?

所以我想得到一个新的 dateTimeList 只包含 dateTime,然后对该列表进行排序,并以某种方式对列表进行排序C

dateTimeList = this.listA
                .map(x => x.dateTime_ISO)
                .concat(this.listB.map(x => x.dateTime));

但是有什么可靠的方法可以对这个 dateTimeList 进行排序吗?

如果仅仅因为两个列表具有不同的字段名称(dateTime_ISO 和 dateTime)而无法完成,那么就假装它们是相同的。我可以将它们修改为在数据库中相同。

感谢任何帮助。

【问题讨论】:

  • stackoverflow.com/questions/6567941/… 的可能重复项;这个问题似乎也不是 Angular 特有的,所以标题有点误导。
  • @dtanabe 感谢您的提示,我将删除角度标签。

标签: javascript arrays


【解决方案1】:

您可以利用短路对组合列表进行排序,同时仍然具有不同的属性。例如:

let listA = [{id:"1234435", name:"apple", dateTime_ISO:"2019-01-15 17:27:30"},{id:"1234435", name:"orange", dateTime_ISO:"2019-01-15 10:25:30"},{id:"1234435", name:"banana", dateTime_ISO:"2019-01-15 10:25:02"},{id:"1234435", name:"pear", dateTime_ISO:"2019-01-15 07:21:52"},{id:"1234435", name:"lemon", dateTime_ISO:"2019-01-15 07:22:24"},]
let listB = [{id:"1234435", name:"bread", dateTime:"2019-01-15 17:27:34"},{id:"1234435", name:"rice", dateTime:"2019-01-15 09:25:30"},{id:"1234435", name:"noodle", dateTime:"2019-01-15 07:25:02"},{id:"1234435", name:"pie", dateTime:"2019-01-15 07:06:52"},{id:"1234435", name:"cake", dateTime:"2019-01-15 06:22:24"},]
  
let listC = listA.concat(listB)

listC.sort((a, b) => {
    return (a.dateTime_ISO || a.dateTime).localeCompare((b.dateTime_ISO || b.dateTime))
})
console.log(listC)

【讨论】:

  • 非常感谢您的解决方案。所以如果我希望它是相反的顺序,我需要申请什么?
  • @Alex 要反转它,您可以交换 ab: listC.sort((b, a)
【解决方案2】:

您可以使用sort(),并在排序条件中检查某些属性是否存在(例如:dateTime_ISO),如果不存在则使用替代属性名称(dateTime):

const listA = [
  {id:"1234435", name:"apple", dateTime_ISO:"2019-01-15 17:27:30"},
  {id:"1234435", name:"orange", dateTime_ISO:"2019-01-15 10:25:30"},
  {id:"1234435", name:"banana", dateTime_ISO:"2019-01-15 10:25:02"},
  {id:"1234435", name:"pear", dateTime_ISO:"2019-01-15 07:21:52"},
  {id:"1234435", name:"lemon", dateTime_ISO:"2019-01-15 07:22:24"},
]

const listB = [
  {id:"1234435", name:"bread", dateTime:"2019-01-15 17:27:34"},
  {id:"1234435", name:"rice", dateTime:"2019-01-15 09:25:30"},
  {id:"1234435", name:"noodle", dateTime:"2019-01-15 07:25:02"},
  {id:"1234435", name:"pie", dateTime:"2019-01-15 07:06:52"},
  {id:"1234435", name:"cake", dateTime:"2019-01-15 06:22:24"},
]

let listC = listA.concat(listB);

// Now, lets sort.

let sortedListC = listC.sort((a, b) =>
{
    let x = (a.dateTime_ISO || a.dateTime);
    let y = (b.dateTime_ISO || b.dateTime);

    return ((x > y) && 1) || ((x < y) && -1) || 0;
});

console.log(sortedListC);

【讨论】:

  • 在排序中使用单个&gt; 测试是不正确的,可能会导致排序不正确。 sort 期望函数返回 -110,而不是 true 或 false。尝试添加具有相同时间的项目。
  • 我明白你所说的,但我试图产生问题,但我不能。任何想法为什么仍然有效?
  • 我认为如果它只返回1和0,它通常会起作用,但这取决于原始顺序。这里有一个古老的威胁:stackoverflow.com/questions/34466125/…
  • @MarkMeyer 感谢您的反馈和帮助理解隐含问题,我已更新为更强大的解决方案。
【解决方案3】:

由于 listA 和 listB 已经按降序排序,我认为您可以利用这一事实并将它们合并。如果您在连接后对结果进行排序,这应该是 O(n) - 而不是 (nlog(n))。

试试这样的

var listA = [
  {id:"1234435", name:"apple", dateTime_ISO:"2019-01-15 17:27:30"},
  {id:"1234435", name:"orange", dateTime_ISO:"2019-01-15 10:25:30"},
  {id:"1234435", name:"banana", dateTime_ISO:"2019-01-15 10:25:02"},
  {id:"1234435", name:"pear", dateTime_ISO:"2019-01-15 07:21:52"},
  {id:"1234435", name:"lemon", dateTime_ISO:"2019-01-15 07:22:24"},
];

var listB = [
  {id:"1234435", name:"bread", dateTime:"2019-01-15 17:27:34"},
  {id:"1234435", name:"rice", dateTime:"2019-01-15 09:25:30"},
  {id:"1234435", name:"noodle", dateTime:"2019-01-15 07:25:02"},
  {id:"1234435", name:"pie", dateTime:"2019-01-15 07:06:52"},
  {id:"1234435", name:"cake", dateTime:"2019-01-15 06:22:24"},
];

function merge(a, b) {
        var ret = [];
        while (a.length && b.length) {
                var smallest = a[0].dateTime_ISO > b[0].dateTime ? a.shift() : b.shift();
                ret.push(smallest);
        }
        return ret.concat(a.length ? a : b);
};

console.log(JSON.stringify(merge(listA, listB), null, 2));

【讨论】:

    【解决方案4】:
    dateTimeList = this.listA.sort(function(a,b){
          //return a.attributes - b.attributes;
          if(a.date < b.date)
              return 1;
          if(a.date > b.date)
              return -1;
        });
    

    是按日期排序的好方法。

    【讨论】:

      猜你喜欢
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-21
      • 2023-03-14
      相关资源
      最近更新 更多