使用相同的键动态合并对象数组并将其创建为新数据(对象数组)
Merge array of object dynamically with same key and create it as new data (array of object)
我有一些对象数组
我想用相同的键合并对象数组,并根据键和值将其创建为新对象
const data =[{
date:"19",
status:"in",
hour:”12:00”
},{
date:"19",
status:"in",
hour:”12:20”
},{
date:"19",
status:"in",
hour:”12:43”
},{
date:"19",
status:"out",
hour:”16:16”
},{
date:"20",
status:"in",
hour:07:30”
},{
date:"20",
status:"out",
hour:”14:40”
},{
date:"21",
status:"in",
hour:”08:12”
}
]
这是我想要的结果
result =[{
date:”19”,
hourIn= “12:00”,
hourOut= “16:16”,
}, {
date:"20",
hourIn:"07:30",
hourOut:14:40”
},{
date:"21",
hourIn:”08:12”,
hourOut:”-“}]
我想如何解决这个问题?
您正在尝试实现一个小型 MapReduce。您可以google了解更多详情。
创建一个地图,其中键是您的日期,值是具有相同日期的对象数组。
现在通过将所有对象插入地图来按日期分隔所有对象。
以输入、输出为第一条件,时间为第二条件对数组进行排序。所以在每个数组中,第一个对象将是时间上的第一个,最后一个对象将是最后一个时间。
将每个数组缩减为一个对象取第一个和最后一个对象。
let map = new Map();
for(让d的数据){
让 t = map.get(d.date)||[];
t.push(d);
map.set(d.date,t);
}
for(让 v of map.values()){
v.sort((a,b)=>a.status < b.status || timecmp(a.hour,b.hour)) // 实现 timecmp
}
让结果=[]
for(让 v of map.values()){
let reduced = // 从 v[0] v[v.length-1] 中获取
结果t.push(减少);
}
这是我的做法,
我遍历了 data
,检查该日期是否已经过去。
如果不是,我检查了status
是in
还是out
,然后设置hour
和date
。
如果通过了,我检查了status
,然后检查时间是早于hourIn
还是晚于已经设置的hourOut
。
let result={};
const data=[{date:"19",status:"in",hour:"12: 00"},{date:"19",status:"in",hour:"12:20"},{date:"19",status:"in",hour:"12:43"},{date:"19",status:"out",hour:"16:16"},{date:"20",status:"in",hour:"07:30"},{date:"20",status:"out",hour:"14:40"},{date:"21",status:"in",hour:"08:12"}];
data.forEach(({ date, status, hour }) => {
if (date in result) {
if (status == 'in' && hour < result[date].hourIn) result[date].hourIn = hour;
else if (status == 'out' && hour > result[date].hourOut) result[date].hourOut = hour;
} else result[date] = {
date,
hourIn: status == 'in' ? hour : '-',
hourOut: status == 'out' ? hour : '-'
};
});
result = Object.values(result);
console.log(result);
既然我已经这样做了,我不确定它会增加多少,但这里有一种使用 reduce 的方法:
const data = [
{date:"19",status:"in",hour:"12:00"}, {date:"19",status:"in",hour:"12:20"}, {date:"19",status:"in",hour:"12:43"}, {date:"19",status:"out",hour:"16:16"},
{date:"20",status:"in",hour:"07:30"}, {date:"20",status:"out",hour:"14:40"},
{date:"21",status:"in",hour:"08:12"}
];
const new_hour = (field, status, current, new_val) =>
field === status &&
(
current === '-' ||
(status === 'in') === (new_val < current)
) ? new_val : current;
const hours_reducer = (acc, { date, status, hour }) =>
Object.assign(acc, {
[date]: {
date,
hourIn: new_hour('in', status, acc[date]?.hourIn || '-', hour),
hourOut: new_hour('out', status, acc[date]?.hourOut || '-', hour),
}
});
const values = Object.values( data.reduce(hours_reducer, {}) );
console.log(values);
我有一些对象数组 我想用相同的键合并对象数组,并根据键和值将其创建为新对象
const data =[{
date:"19",
status:"in",
hour:”12:00”
},{
date:"19",
status:"in",
hour:”12:20”
},{
date:"19",
status:"in",
hour:”12:43”
},{
date:"19",
status:"out",
hour:”16:16”
},{
date:"20",
status:"in",
hour:07:30”
},{
date:"20",
status:"out",
hour:”14:40”
},{
date:"21",
status:"in",
hour:”08:12”
}
]
这是我想要的结果
result =[{
date:”19”,
hourIn= “12:00”,
hourOut= “16:16”,
}, {
date:"20",
hourIn:"07:30",
hourOut:14:40”
},{
date:"21",
hourIn:”08:12”,
hourOut:”-“}]
我想如何解决这个问题?
您正在尝试实现一个小型 MapReduce。您可以google了解更多详情。
创建一个地图,其中键是您的日期,值是具有相同日期的对象数组。
现在通过将所有对象插入地图来按日期分隔所有对象。
以输入、输出为第一条件,时间为第二条件对数组进行排序。所以在每个数组中,第一个对象将是时间上的第一个,最后一个对象将是最后一个时间。
将每个数组缩减为一个对象取第一个和最后一个对象。
let map = new Map();
for(让d的数据){ 让 t = map.get(d.date)||[]; t.push(d); map.set(d.date,t); }
for(让 v of map.values()){ v.sort((a,b)=>a.status < b.status || timecmp(a.hour,b.hour)) // 实现 timecmp }
让结果=[]
for(让 v of map.values()){ let reduced = // 从 v[0] v[v.length-1] 中获取 结果t.push(减少); }
这是我的做法,
我遍历了 data
,检查该日期是否已经过去。
如果不是,我检查了status
是in
还是out
,然后设置hour
和date
。
如果通过了,我检查了status
,然后检查时间是早于hourIn
还是晚于已经设置的hourOut
。
let result={};
const data=[{date:"19",status:"in",hour:"12: 00"},{date:"19",status:"in",hour:"12:20"},{date:"19",status:"in",hour:"12:43"},{date:"19",status:"out",hour:"16:16"},{date:"20",status:"in",hour:"07:30"},{date:"20",status:"out",hour:"14:40"},{date:"21",status:"in",hour:"08:12"}];
data.forEach(({ date, status, hour }) => {
if (date in result) {
if (status == 'in' && hour < result[date].hourIn) result[date].hourIn = hour;
else if (status == 'out' && hour > result[date].hourOut) result[date].hourOut = hour;
} else result[date] = {
date,
hourIn: status == 'in' ? hour : '-',
hourOut: status == 'out' ? hour : '-'
};
});
result = Object.values(result);
console.log(result);
既然我已经这样做了,我不确定它会增加多少,但这里有一种使用 reduce 的方法:
const data = [
{date:"19",status:"in",hour:"12:00"}, {date:"19",status:"in",hour:"12:20"}, {date:"19",status:"in",hour:"12:43"}, {date:"19",status:"out",hour:"16:16"},
{date:"20",status:"in",hour:"07:30"}, {date:"20",status:"out",hour:"14:40"},
{date:"21",status:"in",hour:"08:12"}
];
const new_hour = (field, status, current, new_val) =>
field === status &&
(
current === '-' ||
(status === 'in') === (new_val < current)
) ? new_val : current;
const hours_reducer = (acc, { date, status, hour }) =>
Object.assign(acc, {
[date]: {
date,
hourIn: new_hour('in', status, acc[date]?.hourIn || '-', hour),
hourOut: new_hour('out', status, acc[date]?.hourOut || '-', hour),
}
});
const values = Object.values( data.reduce(hours_reducer, {}) );
console.log(values);