使用javascript创建累积对象
我有一个日期数组和一个对象数组。每个都有一个日期属性。我需要按日期对对象进行累积排序。因此,对于date数组中的每个日期,我希望创建一个累积对象,其中每个对象的date属性早于date数组中的日期 例如,以下日期数组和对象数组:使用javascript创建累积对象,javascript,arrays,sorting,date,for-loop,Javascript,Arrays,Sorting,Date,For Loop,我有一个日期数组和一个对象数组。每个都有一个日期属性。我需要按日期对对象进行累积排序。因此,对于date数组中的每个日期,我希望创建一个累积对象,其中每个对象的date属性早于date数组中的日期 例如,以下日期数组和对象数组: ['2017-11-5', '2018-3-1', '2018-3-22'] [{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-
['2017-11-5', '2018-3-1', '2018-3-22']
[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}, {name: 'Jack', date: '2018-3-21'}]
[{name: 'Jes', date: '2017-11-2'}]
[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}]
[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}, {name: 'Jack', date: '2018-3-21'}]
所需输出为:
['2017-11-5', '2018-3-1', '2018-3-22']
[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}, {name: 'Jack', date: '2018-3-21'}]
[{name: 'Jes', date: '2017-11-2'}]
[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}]
[{name: 'Jes', date: '2017-11-2'}, {name: 'Jill', date: '2018-1-5'}, {name: 'Joe', date: '2018-2-25'}, {name: 'Jack', date: '2018-3-21'}]
我试图用大约500个日期和30000个对象来完成这项工作
这是一个最新的代码片段,但由于迭代对象的数量,我遇到了性能问题
_.each(dtArray,function(i:Date){
let dt = new Date(i);
let filtered = _.filter(data,function(row){
let dtVal = new Date(row['date']);
return dtVal<=dt;
});
\每个(dtArray,function)(i:Date){
设dt=新日期(i);
let filtered=\过滤器(数据,函数(行){
设dtVal=新日期(行['Date']);
return dtVal由于您希望每个日期都有一个结果数组,因此您可以在日期之间切换。然后,您可以在地图中根据日期选择人员以创建该数组:
let dates=['2017-11-5','2018-3-1','2018-3-22']
let people=[{姓名:'Jes',日期:'2017-11-2'},{姓名:'Jill',日期:'2018-1-5'},{姓名:'Joe',日期:'2018-2-25'},{姓名:'Jack',日期:'2018-3-21'}]
让cumul=dates.map(d=>people.filter(person=>person.date您可以对日期进行筛选,因为您希望每个日期都有一个结果数组。然后在映射中,您可以根据创建该数组的日期选择人员:
let dates=['2017-11-5','2018-3-1','2018-3-22']
let people=[{姓名:'Jes',日期:'2017-11-2'},{姓名:'Jill',日期:'2018-1-5'},{姓名:'Joe',日期:'2018-2-25'},{姓名:'Jack',日期:'2018-3-21'}]
让cumul=dates.map(d=>people.filter(person=>person.date在保持关联索引的同时,有几种方法可以改进算法:
- 预先计算日期对象,只为
人员
和日期
- 以升序方式对日期进行排序
- 重新使用预先计算/预过滤的结果,请参阅
- 保存
日期
和人员
索引以保持原始顺序
- 在
剩余的
和lastChunk
之间交换项目,以减少剩余的
大小,如果人员[i]。日期
算法代码:
function filter(dates, people){
let lastChunk = [];
let remaining = people;
let results = [];
// precalculate dates, preserve indexes and sort by date
let sortedDates = dates
.map((value, index) => {
return {
date: new Date(value),
index: index
};
})
.sort((a, b) => {
return a.date<b.date?-1:a.date==b.date?0:1;
});
let peopleWithDates = people.map((value, index) => {
value.dateObject = new Date(value.date);
value.index = index;
return value;
});
for(const i in sortedDates){
const comp = sortedDates[i].date
remaining = remaining.filter((value, index) => {
if(value.dateObject<=comp){
let itemIndex = value.index;
delete value.dateObject;
delete value.index;
lastChunk.splice(itemIndex, 0, value);
return false;
}else{
return true;
}
});
results[sortedDates[i].index] = [...lastChunk];
}
return results;
}
函数过滤器(日期、人员){
设lastChunk=[];
让剩余=人;
让结果=[];
//预先计算日期,保留索引并按日期排序
让我们看看日期
.map((值、索引)=>{
返回{
日期:新日期(值),
索引:索引
};
})
.排序((a,b)=>{
返回日期{
value.dateObject=新日期(value.Date);
value.index=索引;
返回值;
});
用于(分类数据中的常数i){
const comp=sortedDates[i]。日期
剩余=剩余。筛选器((值、索引)=>{
如果(value.dateObject有几种方法可以改进算法,同时保持关联索引:
- 预先计算日期对象,只为
人员
和日期
- 以升序方式对日期进行排序
- 重新使用预先计算/预过滤的结果,请参阅
- 保存
日期
和人员
索引以保持原始顺序
- 在
剩余的
和lastChunk
之间交换项目,以减少剩余的
大小,如果人员[i]。日期
算法代码:
function filter(dates, people){
let lastChunk = [];
let remaining = people;
let results = [];
// precalculate dates, preserve indexes and sort by date
let sortedDates = dates
.map((value, index) => {
return {
date: new Date(value),
index: index
};
})
.sort((a, b) => {
return a.date<b.date?-1:a.date==b.date?0:1;
});
let peopleWithDates = people.map((value, index) => {
value.dateObject = new Date(value.date);
value.index = index;
return value;
});
for(const i in sortedDates){
const comp = sortedDates[i].date
remaining = remaining.filter((value, index) => {
if(value.dateObject<=comp){
let itemIndex = value.index;
delete value.dateObject;
delete value.index;
lastChunk.splice(itemIndex, 0, value);
return false;
}else{
return true;
}
});
results[sortedDates[i].index] = [...lastChunk];
}
return results;
}
函数过滤器(日期、人员){
设lastChunk=[];
让剩余=人;
让结果=[];
//预先计算日期,保留索引并按日期排序
让我们看看日期
.map((值、索引)=>{
返回{
日期:新日期(值),
索引:索引
};
})
.排序((a,b)=>{
返回日期{
value.dateObject=新日期(value.Date);
value.index=索引;
返回值;
});
用于(分类数据中的常数i){
const comp=sortedDates[i]。日期
剩余=剩余。筛选器((值、索引)=>{
如果(value.dateobject感谢您指出out Joe,您是正确的,我已更正了所需结果如果您能够将日期格式化为YYYY-MM-DD,它们将按词汇排序,因此更易于处理。感谢您指出out Joe,您是正确的,我已更正了所需结果如果您能够将日期格式化为YYYY-MM-DD,它们将按词汇进行排序,因此更易于处理。谢谢mark!这将创建我要查找的累积数组,但它只返回日期值,如何还可以包含name属性?@user2821694我运行此代码段时看到name
。您没有这样做吗?这将无法可靠地按照给定的person.date运行ht@RobG。如果日期为ISO 8601(即2018-11-02),则会有所帮助@Mark Meyer,这个解决方案确实对我有效,但是它没有提高性能,当我使用我的真实数据集时,它需要50-60秒才能运行谢谢Mark!这会创建我正在寻找的累积数组,但它只返回日期值,怎么还可以包括name属性?@user2821694我看到name
当我n这段代码。你不是吗?如果给定person.date You's right@RobG,这将无法可靠地工作。如果日期是ISO 8601(即2018-11-02),这将很有帮助@Mark Meyer,此解决方案确实对我有效,但它没有提高性能,当我使用真实数据集新日期(值)时,运行此解决方案需要50-60秒
将导致Safari中的日期无效,至少因为时间戳不符合ECMA-262中指定的任何格式。可以这样解决:const parseDate=date=>new date(date+“T00:00:00”);
whi