三个元素的排序数组
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
。
然后,我们遍历现在排序的数据并跟踪我们访问的前一个项目。每当我们看到主排序键中断(名称更改)时,我们就知道我们有所需的项目(例如,给定名称的记录具有最短的进入时间),我们将其推入唯一项目集。我们知道如果
我们有一个序列中断
- 没有上一项。这仅适用于列表中的第一项。
- 如果当前和上一个项目的名称不同。
这使我们找到了这个解决方案。
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());
我正在开发 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
。然后,我们遍历现在排序的数据并跟踪我们访问的前一个项目。每当我们看到主排序键中断(名称更改)时,我们就知道我们有所需的项目(例如,给定名称的记录具有最短的进入时间),我们将其推入唯一项目集。我们知道如果
我们有一个序列中断- 没有上一项。这仅适用于列表中的第一项。
- 如果当前和上一个项目的名称不同。
这使我们找到了这个解决方案。
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());