javascript - 如何重构和映射数组以适应 React 中的指定数据结构
问题描述
我正在使用 reaviz 是 React 的图表工具。我正在创建一个习惯跟踪器应用程序,并希望在一系列条形图上直观地显示用户输入最后一周的数据。我的数据库中的数据结构如下:
habits = [
{
habit: "Cook Dinner",
inputs: [
{
input: 'Success',
date: 'Oct 5th 21'
},
{
input: 'Fail',
date: 'Oct 6th 21'
},
{
input: 'Skip',
date: 'Oct 7th 21'
}]
},
{
habit: "Clean House",
inputs: [
{
input: 'Fail',
date: 'Oct 5th 21'
},
{
input: 'Fail',
date: 'Oct 6th 21'
},
{
input: 'Fail',
date: 'Oct 7th 21'
}]
},
{
habit: "Cook Dinner",
inputs: [
{
input: 'Success',
date: 'Oct 5th 21'
},
{
input: 'Fail',
date: 'Oct 6th 21'
},
{
input: 'Skip',
date: 'Oct 7th 21'
}]
}]
所以现在我想找出一种方法将我的数据映射到图表所需的数据结构,例如,对于上述数据,输出将是这样的。我需要计算当天有多少输入是成功、失败或跳过:
habitsMappedData = [
{
key: 'Oct 5th 21',
data: [
{
key: 'Success',
data: 2
},
{
key: 'Fail',
data: 1
},
{
key: 'Skip',
data: 0
}
]
}, {
key: 'Oct 6th 21',
data: [
{
key: 'Sucess',
data: 0
},
{
key: 'Fail',
data: 3
},
{
key: 'Skip',
data: 0
}
]
}, {
key: 'Oct 7th 21',
data: [
{
key: 'Success',
data: 0
},
{
key: 'Fail',
data: 1
},
{
key: 'Skip',
data: 2
}
]
},
]
非常感谢您浏览此内容。如果需要任何澄清,请告诉我。
解决方案
这实际上只是按日期进行的“分组”操作,但由于嵌套数组,它涉及更多一点。
下面的代码片段使用reduce()
调用来累积到使用date
作为分组属性的对象中,并使用input
作为辅助属性求和。要将生成的对象转换回嵌套对象的数组,它调用返回对象Array.from()
的并使用提供的作为 的第二个参数Object.entries()
映射key
和data
属性。嵌套对象是使用最终调用生成的。map
Array.from()
data
map()
const habits = [ { habit: 'Cook Dinner', inputs: [ { input: 'Success', date: 'Oct 5th 21', }, { input: 'Fail', date: 'Oct 6th 21', }, { input: 'Skip', date: 'Oct 7th 21', }, ], }, { habit: 'Clean House', inputs: [ { input: 'Fail', date: 'Oct 5th 21', }, { input: 'Fail', date: 'Oct 6th 21', }, { input: 'Fail', date: 'Oct 7th 21', }, ], }, { habit: 'Cook Dinner', inputs: [ { input: 'Success', date: 'Oct 5th 21', }, { input: 'Fail', date: 'Oct 6th 21', }, { input: 'Skip', date: 'Oct 7th 21', }, ], }, ];
const habitsMappedData = Array.from(
Object.entries(
habits.reduce((a, { inputs }) => {
for (const { date, input } of inputs) {
(a[date] ??= { Success: 0, Fail: 0, Skip: 0 })[input] += 1;
}
return a;
}, {})
),
([key, _data]) => ({
key,
data: Object.entries(_data).map(([key, data]) => ({ key, data })),
})
);
console.log(habitsMappedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }
注意:以上依赖于逻辑空赋值运算符 (??=),如果需要兼容性,可以将其替换为OR
短路。
for (const { date, input } of inputs) {
(a[date] || (a[date] = { Success: 0, Fail: 0, Skip: 0 }))[input] += 1;
}
或明确写出if
for (const { date, input } of inputs) {
if (a[date] === undefined) {
a[date] = { Success: 0, Fail: 0, Skip: 0 };
}
a[date][input] += 1;
}
推荐阅读
- laravel - 如何调用 .env {{ env('APP_NAME} }} 到 laravel 刀片模板?
- c# - uwp beforetextchanged 光标在文本前面移动
- ibm-cloud - 如何仅从变量中提取数字
- python - Python pdf2txt 清理问题
- python - 有没有办法用 matplotlib 自动制作“拼贴”的图?
- sql-server - 在 SQL CLR 中使用套接字 API
- laravel - Laravel How to use external variable on join
- javascript - 如何使用 JQuery 替换脚本标签中的文本
- python - 如何在没有明显 url 的情况下从搜索结果中抓取 pdf 和 html
- javascript - Angular Reactive Form Validator.min/max 在检查值之前检查执行类型转换吗?