Filter/Reduce 根据日期将对象数组转换为新对象
Filter/Reduce array of objects into a new object based on day
考虑以下对象数组:
const data = [
*{...more data from previous dates}*,
{
unixDate: 1650348034, //yesterday
dateTime: Tue Apr 19 2022 23:00:34,
severityLevel: 1,
severity: "Light"
},
{
unixDate: 1650348034, //yesterday
dateTime: Tue Apr 19 2022 14:00:34,
severityLevel: 3,
severity: "Moderate"
},
{
unixDate: 1650440700, //today
dateTime: Wed Apr 20 2022 15:45:00,
severityLevel: 2,
severity: "Moderate-Light"
},
{
unixDate: 1650442500, //today
dateTime: Wed Apr 20 2022 15:45:00,
severityLevel: 4,
severity: "Heavy"
},
{
unixDate: 1650427234, //today
dateTime: Wed Apr 20 2022 12:00:00,
severityLevel: 3,
severity: "Moderate"
}
]
我想return以下内容:
{
*///...records from previous dates,*
1650348034 : 2, //yesterday record taking only one of the unixtimestamp, and the average value of 'severityLevel'.
1650440700 : 3 //same as above but unixtimestamp is today.
}
我正在使用 dayjs
包通过 isToday
插件来确定日期是否是今天,但想不出如何比较日期。 data
每天都在增长,因为它记录了新的读数。我不太熟悉 ES6 中的数组 filter/reduce 方法,它们在这里有用吗?感谢您的帮助!
首先你需要将这些 unix 时间转换为 javascript Date
对象。然后您可以按 year/month/date 分组,然后对结果进行平均。
const data = [
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 23:00:34",
severityLevel: 1,
severity: "Light"
},
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 14:00:34",
severityLevel: 3,
severity: "Moderate"
},
{
unixDate: 1650440700, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 2,
severity: "Moderate-Light"
},
{
unixDate: 1650442500, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 4,
severity: "Heavy"
},
{
unixDate: 1650427234, //today
dateTime: "Wed Apr 20 2022 12:00:00",
severityLevel: 3,
severity: "Moderate"
}
]
const x = Object.values(data.map(x => ({...x, dateTime: new Date(x.unixDate * 1000)}))
.reduce( (acc,i) => {
const key = "" + i.dateTime.getFullYear() + i.dateTime.getMonth() + i.dateTime.getDate();
acc[key] = acc[key] || [];
acc[key].push(i);
return acc
},{}))
.reduce( (obj,rec) => {
return {...obj, [rec[0].unixDate]: rec.reduce( (acc,i) => acc+i.severityLevel,0) / rec.length }
},{})
console.log(x)
请注意,如果 属性 dateTime
已经是 javascript 日期,您可以不使用 data.map(x => ({...x, dateTime: new Date(x.unixDate * 1000)}))
部分。
获取唯一的天数列表并根据计算出的天数构建对象
const data = [ { unixDate: 1650348034, dateTime: "Tue Apr 19 2022 23:00:34", severityLevel: 1, severity: "Light" }, { unixDate: 1650348034, dateTime: "Tue Apr 19 2022 14:00:34", severityLevel: 3, severity: "Moderate" }, { unixDate: 1650440700, dateTime: "Wed Apr 20 2022 15:45:00", severityLevel: 2, severity: "Moderate-Light" }, { unixDate: 1650442500, dateTime: "Wed Apr 20 2022 15:45:00", severityLevel: 4, severity: "Heavy" }, { unixDate: 1650427234, dateTime: "Wed Apr 20 2022 12:00:00", severityLevel: 3, severity: "Moderate" } ]
//Get unique list of days
let unique = [... new Set(data.map(d => new Date(d.unixDate * 1000).toLocaleDateString("en-US")))];
//build object based on this list
let results = Object.fromEntries(unique.map(m => {
let records = data.filter(v => new Date(v.unixDate * 1000).toLocaleDateString("en-US") === m);
return [records[0].unixDate, records.reduce((v,o) => v+=o.severityLevel, 0) / records.length ]
}));
console.log(results);
您正在寻找的方法是Array.map(),它很容易使用,您在数组上调用它并提供一个函数,该函数将为每个索引return 新数据, 而原文是提供当它自己的功能时。
要完成您想做的事,您还必须使用 Object.fromEntries() 将数组转换为对象。以下是您的操作方法:
let newData = Object.fromEntries(data.map((d)=>[d.unixDate, d.severityLevel]));
此代码将首先将您的数据转换为包含数组的数组,其中 0 索引是键也就是时间戳,1 索引是该键的数据也就是您的严重级别。它看起来像这样:
[
[1650348034,1],
[1650348034,3],
[1650440700,2],
[1650442500,4],
[1650427234,3]
]
然后转换为你的对象
查看此处了解更多信息:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
希望这对您有所帮助
好吧,我希望我理解正确。这是一个示例,说明如何实现与所需输出类似的结果:
//input
const data = [
{
"unixDate": 1650348034, //yesterday
"dateTime": "Tue Apr 19 2022 23:00:34",
"severityLevel": 1,
"severity": "Light"
},
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 14:00:34",
severityLevel: 3,
severity: "Moderate"
},
{
unixDate: 1650440700, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 2,
severity: "Moderate-Light"
},
{
unixDate: 1650442500, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 4,
severity: "Heavy"
},
{
unixDate: 1650427234, //today
dateTime: "Wed Apr 20 2022 12:00:00",
severityLevel: 3,
severity: "Moderate"
}
];
// ES6 computed property syntax
const arr = data.map(x => { return { [x.unixDate]: x.severityLevel }});
//output
console.log(arr.reduce(function(result, current) {
return Object.assign(result, current);
}, {}));
另一种使用 util 方法的方法 dayBegins
将计算日期开始时间戳。这将有助于确定时间戳是否属于同一天。
除此之外,只需构建一个跟踪对象,其键为 dayBegin,值具有 severityLevel 和出现次数。
const dayBegins = (uDate) =>
"" + uDate * 1000 - ((uDate * 1000) % (24 * 60 * 60 * 1000));
const process = (arr, output = {}) => {
arr.forEach(({ unixDate, severityLevel }) => {
const key = dayBegins(unixDate);
if (key in output) {
output[key].count += 1;
output[key].sum += severityLevel;
} else {
output[key] = {
unixDate,
count: 1,
sum: severityLevel,
};
}
});
return Object.values(output).reduce(
(acc, { unixDate, sum, count }) =>
Object.assign(acc, { [unixDate]: sum / count }),
{}
);
};
const data = [
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 23:00:34",
severityLevel: 1,
severity: "Light",
},
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 14:00:34",
severityLevel: 3,
severity: "Moderate",
},
{
unixDate: 1650440700, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 2,
severity: "Moderate-Light",
},
{
unixDate: 1650442500, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 4,
severity: "Heavy",
},
{
unixDate: 1650427234, //today
dateTime: "Wed Apr 20 2022 12:00:00",
severityLevel: 3,
severity: "Moderate",
},
];
console.log(process(data))
考虑以下对象数组:
const data = [
*{...more data from previous dates}*,
{
unixDate: 1650348034, //yesterday
dateTime: Tue Apr 19 2022 23:00:34,
severityLevel: 1,
severity: "Light"
},
{
unixDate: 1650348034, //yesterday
dateTime: Tue Apr 19 2022 14:00:34,
severityLevel: 3,
severity: "Moderate"
},
{
unixDate: 1650440700, //today
dateTime: Wed Apr 20 2022 15:45:00,
severityLevel: 2,
severity: "Moderate-Light"
},
{
unixDate: 1650442500, //today
dateTime: Wed Apr 20 2022 15:45:00,
severityLevel: 4,
severity: "Heavy"
},
{
unixDate: 1650427234, //today
dateTime: Wed Apr 20 2022 12:00:00,
severityLevel: 3,
severity: "Moderate"
}
]
我想return以下内容:
{
*///...records from previous dates,*
1650348034 : 2, //yesterday record taking only one of the unixtimestamp, and the average value of 'severityLevel'.
1650440700 : 3 //same as above but unixtimestamp is today.
}
我正在使用 dayjs
包通过 isToday
插件来确定日期是否是今天,但想不出如何比较日期。 data
每天都在增长,因为它记录了新的读数。我不太熟悉 ES6 中的数组 filter/reduce 方法,它们在这里有用吗?感谢您的帮助!
首先你需要将这些 unix 时间转换为 javascript Date
对象。然后您可以按 year/month/date 分组,然后对结果进行平均。
const data = [
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 23:00:34",
severityLevel: 1,
severity: "Light"
},
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 14:00:34",
severityLevel: 3,
severity: "Moderate"
},
{
unixDate: 1650440700, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 2,
severity: "Moderate-Light"
},
{
unixDate: 1650442500, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 4,
severity: "Heavy"
},
{
unixDate: 1650427234, //today
dateTime: "Wed Apr 20 2022 12:00:00",
severityLevel: 3,
severity: "Moderate"
}
]
const x = Object.values(data.map(x => ({...x, dateTime: new Date(x.unixDate * 1000)}))
.reduce( (acc,i) => {
const key = "" + i.dateTime.getFullYear() + i.dateTime.getMonth() + i.dateTime.getDate();
acc[key] = acc[key] || [];
acc[key].push(i);
return acc
},{}))
.reduce( (obj,rec) => {
return {...obj, [rec[0].unixDate]: rec.reduce( (acc,i) => acc+i.severityLevel,0) / rec.length }
},{})
console.log(x)
请注意,如果 属性 dateTime
已经是 javascript 日期,您可以不使用 data.map(x => ({...x, dateTime: new Date(x.unixDate * 1000)}))
部分。
获取唯一的天数列表并根据计算出的天数构建对象
const data = [ { unixDate: 1650348034, dateTime: "Tue Apr 19 2022 23:00:34", severityLevel: 1, severity: "Light" }, { unixDate: 1650348034, dateTime: "Tue Apr 19 2022 14:00:34", severityLevel: 3, severity: "Moderate" }, { unixDate: 1650440700, dateTime: "Wed Apr 20 2022 15:45:00", severityLevel: 2, severity: "Moderate-Light" }, { unixDate: 1650442500, dateTime: "Wed Apr 20 2022 15:45:00", severityLevel: 4, severity: "Heavy" }, { unixDate: 1650427234, dateTime: "Wed Apr 20 2022 12:00:00", severityLevel: 3, severity: "Moderate" } ]
//Get unique list of days
let unique = [... new Set(data.map(d => new Date(d.unixDate * 1000).toLocaleDateString("en-US")))];
//build object based on this list
let results = Object.fromEntries(unique.map(m => {
let records = data.filter(v => new Date(v.unixDate * 1000).toLocaleDateString("en-US") === m);
return [records[0].unixDate, records.reduce((v,o) => v+=o.severityLevel, 0) / records.length ]
}));
console.log(results);
您正在寻找的方法是Array.map(),它很容易使用,您在数组上调用它并提供一个函数,该函数将为每个索引return 新数据, 而原文是提供当它自己的功能时。
要完成您想做的事,您还必须使用 Object.fromEntries() 将数组转换为对象。以下是您的操作方法:
let newData = Object.fromEntries(data.map((d)=>[d.unixDate, d.severityLevel]));
此代码将首先将您的数据转换为包含数组的数组,其中 0 索引是键也就是时间戳,1 索引是该键的数据也就是您的严重级别。它看起来像这样:
[
[1650348034,1],
[1650348034,3],
[1650440700,2],
[1650442500,4],
[1650427234,3]
]
然后转换为你的对象
查看此处了解更多信息:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
希望这对您有所帮助
好吧,我希望我理解正确。这是一个示例,说明如何实现与所需输出类似的结果:
//input
const data = [
{
"unixDate": 1650348034, //yesterday
"dateTime": "Tue Apr 19 2022 23:00:34",
"severityLevel": 1,
"severity": "Light"
},
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 14:00:34",
severityLevel: 3,
severity: "Moderate"
},
{
unixDate: 1650440700, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 2,
severity: "Moderate-Light"
},
{
unixDate: 1650442500, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 4,
severity: "Heavy"
},
{
unixDate: 1650427234, //today
dateTime: "Wed Apr 20 2022 12:00:00",
severityLevel: 3,
severity: "Moderate"
}
];
// ES6 computed property syntax
const arr = data.map(x => { return { [x.unixDate]: x.severityLevel }});
//output
console.log(arr.reduce(function(result, current) {
return Object.assign(result, current);
}, {}));
另一种使用 util 方法的方法 dayBegins
将计算日期开始时间戳。这将有助于确定时间戳是否属于同一天。
除此之外,只需构建一个跟踪对象,其键为 dayBegin,值具有 severityLevel 和出现次数。
const dayBegins = (uDate) =>
"" + uDate * 1000 - ((uDate * 1000) % (24 * 60 * 60 * 1000));
const process = (arr, output = {}) => {
arr.forEach(({ unixDate, severityLevel }) => {
const key = dayBegins(unixDate);
if (key in output) {
output[key].count += 1;
output[key].sum += severityLevel;
} else {
output[key] = {
unixDate,
count: 1,
sum: severityLevel,
};
}
});
return Object.values(output).reduce(
(acc, { unixDate, sum, count }) =>
Object.assign(acc, { [unixDate]: sum / count }),
{}
);
};
const data = [
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 23:00:34",
severityLevel: 1,
severity: "Light",
},
{
unixDate: 1650348034, //yesterday
dateTime: "Tue Apr 19 2022 14:00:34",
severityLevel: 3,
severity: "Moderate",
},
{
unixDate: 1650440700, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 2,
severity: "Moderate-Light",
},
{
unixDate: 1650442500, //today
dateTime: "Wed Apr 20 2022 15:45:00",
severityLevel: 4,
severity: "Heavy",
},
{
unixDate: 1650427234, //today
dateTime: "Wed Apr 20 2022 12:00:00",
severityLevel: 3,
severity: "Moderate",
},
];
console.log(process(data))