三个元素的排序数组

Sorting array for three elemets

我正在开发 angular 应用程序。我有以下数组。

[
 {
        "Name": "Jack",
        "IncomingTime": "2020-06-19T11:02+00:00",
        "Outgoingtime": "2020-06-19T11:07+00:00",
  },
  {
        "Name": "Mary",
        "IncomingTime": "2020-06-19T11:05+00:00",
        "Outgoingtime": "2020-06-19T11:07+00:00",
  },
  {
        "Name": "jolly",
        "IncomingTime": "2020-06-19T11:05+00:00",
        "Outgoingtime": "2020-06-19T11:07+00:00",
  },
  {
        "Name": "Jack",
        "IncomingTime": "2020-06-19T11:05+00:00",
        "Outgoingtime": "2020-06-19T11:07+00:00",
  },
  {
        "Name": "Maria",
        "IncomingTime": "2020-06-19T11:05+00:00",
        "Outgoingtime": "2020-06-19T11:17+00:00",
  },
   {
        "Name": "Maria",
        "IncomingTime": "2020-06-19T11:05+00:00",
        "Outgoingtime": "2020-06-19T12:53+00:00",
  },
  {
        "Name": "Jack",
        "IncomingTime": "2020-06-19T11:05+00:00",
        "Outgoingtime": "2020-06-19T11:07+00:00",
  } 
]

我想实现一个独一无二的数组。我想对这个数组中的元素进行排序,它应该首先按名称的字母顺序对所有元素进行排序。如果名称相同,那么我想按传入时间排序。例如 person with "Name': "jack' 出现了 3 次,那么进入时间早的 Jack 应该放在数组中,即 "2020-06-19T11:02+00:00" 并且剩下两个 "jack" 元素他们有相同的传入和传出时间被丢弃(因为我们已经在数组中包含了一个早期的传入时间)。如果“Name”和“IncomingTime”也相同,例如“Maria”,只有两个元素和“Name”,“IncomingTime”相同,那么我想保留早期传出时间的元素,即应该在结果数组中应该是“OutgointTime”:“2020-06-19T11:17+00:00”,另一个带有“OutgointTime”12:53的被丢弃。我怎样才能做到这一点?

不确定,但像这样..

aa.sort(
    function (a, b) {

        // try names
        if (a["Name"] < b["Name"])
            return -1;
        else if (a["Name"] > b["Name"])
            return 1;

        // if names are equal compare IncomingTime
        if (a["IncomingTime"] < b["IncomingTime"])
            return -1;
        else if (a["IncomingTime"] > b["IncomingTime"])
            return 1;



        return 0;
    }
);

您可以只使用 lodash 按功能排序。

import * as _ from 'lodash'

let sorted_collection = _.sortBy(collection, ['Name', 'IncomingTime', 'Outgoingtime'])

_.sortBy 将应用多级排序。请检查一下。

在 TypeScript 中 Mayank Gupta 的代码是这样的

a.sort((a:any, b:any) => a.Name>b.Name?1:a.Name<b.Name?-1:
                       a.IncomingTime>b.IncomingTime?1: a.IncomingTime<b.IncomingTime?-1:
                       a.Outgoingtime>b.Outgoingtime?1:
                       a.Outgoingtime<b.Outgoingtime?-1:0)

鉴于您的原始数据,

const rawData = [
  { "Name": "Jack",  "IncomingTime": "2020-06-19T11:02+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
  { "Name": "Mary",  "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
  { "Name": "jolly", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
  { "Name": "Jack",  "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
  { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:17+00:00", },
  { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T12:53+00:00", },
  { "Name": "Jack",  "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }
];

为了得到您想要的,我们执行以下操作:

  • 首先,将原始数据按Name排序,然后IncomingTime,然后OutgoingTime

  • 然后,我们遍历现在排序的数据并跟踪我们访问的前一个项目。每当我们看到主排序键中断(名称更改)时,我们就知道我们有所需的项目(例如,给定名称的记录具有最短的进入时间),我们将其推入唯一项目集。我们知道如果

    我们有一个序列中断
    1. 没有上一项。这仅适用于列表中的第一项。
    2. 如果当前和上一个项目的名称不同。

这使我们找到了这个解决方案。

const sortedData = rawData.sort(
  (x,y) => x.Name         < y.Name         ? -1 // sort by name
         : x.Name         > y.Name         ? +1 //
         : x.IncomingTime < y.IncomingTime ? -1 // then by incoming time
         : x.IncomingTime > y.IncomingTime ? +1 //
         : x.Outgoingtime < y.Outgoingtime ? -1 // then by outgoing time
         : x.Outgoingtime > y.Outgoingtime ? +1
         :                                    0 // both items compare equal
);
const uniqueData = [];
let prev;
for (const curr of sortedData) {
  if ( !prev || curr.Name !== prev.Name ) {
    uniqueData.push(curr);
  }
  prev = curr;
}
console.log(JSON.stringify(uniqueData,undefined,2));

产生

[
  {
    "Name": "Jack",
    "IncomingTime": "2020-06-19T11:02+00:00",
    "Outgoingtime": "2020-06-19T11:07+00:00"
  },
  {
    "Name": "Maria",
    "IncomingTime": "2020-06-19T11:05+00:00",
    "Outgoingtime": "2020-06-19T11:17+00:00"
  },
  {
    "Name": "Mary",
    "IncomingTime": "2020-06-19T11:05+00:00",
    "Outgoingtime": "2020-06-19T11:07+00:00"
  },
  {
    "Name": "jolly",
    "IncomingTime": "2020-06-19T11:05+00:00",
    "Outgoingtime": "2020-06-19T11:07+00:00"
  }
]

一个可以说更简单的解决方案可能是使用 Map。这完成了同样的事情(为有序列表中的每个名称获取第一个条目)。 Map 的好处在于,与普通对象不同,数据保证按插入顺序返回,因此排序列表的顺序保持不变:

const sortedData = rawData.sort(
  (x,y) => x.Name         < y.Name         ? -1 // sort by name
         : x.Name         > y.Name         ? +1 //
         : x.IncomingTime < y.IncomingTime ? -1 // then by incoming time
         : x.IncomingTime > y.IncomingTime ? +1 //
         : x.Outgoingtime < y.Outgoingtime ? -1 // then by outgoing time
         : x.Outgoingtime > y.Outgoingtime ? +1
         :                                    0 // both items compare equal
);

const map = new Map();
for (const entry of sortedData) {
  const value = map.get(entry.Name);
  if (!value) {
    map.set(entry.Name, entry);
  }
}

const uniqueData = Array.from(map.values());