javascript - 按日期减少对象
问题描述
我有一个这样的数组:
transactionData = [
{ MaterialID: "3000745",
TransactionQuantity: "2.000",
TransactionDate: "01/15/2020"
},
{ MaterialID: "3000745",
TransactionQuantity: "3.000",
TransactionDate: "2/24/2020"
},
{ MaterialID: "3000051",
TransactionQuantity: "1.000",
TransactionDate: "3/10/2020"
},
{ MaterialID: "3000051",
TransactionQuantity: "1.000",
TransactionDate: "4/01/2020"
}
]
像这样的对象:
dateObj = {
"Jan-20": { sum: 0, count: 0 },
"Feb-20": { sum: 0, count: 0 },
"Mar-20": { sum: 0, count: 0 },
"Apr-20": { sum: 0, count: 0 }
}
我正在尝试减少 transactionData 并返回这样的对象:
{
"3000051": {
"monthlyVolume": {
"Jan-20": {
"sum": 0,
"count": 0
},
"Feb-20": {
"sum": 0,
"count": 0
},
"Mar-20": {
"sum": 1,
"count": 1
},
"Apr-20": {
"sum": 1,
"count": 1
}
}
},
"3000745": {
"monthlyVolume": {
"Jan-20": {
"sum": 2,
"count": 1
},
"Feb-20": {
"sum": 3,
"count": 1
},
"Mar-20": {
"sum": 0,
"count": 0
},
"Apr-20": {
"sum": 0,
"count": 0
}
}
}
}
出于某种原因,我的 reduce 函数为两个 MaterialID 返回相同的值。我已经为此工作了几个小时,无法弄清楚我做错了什么。我将感谢 SO 社区的任何帮助。
下面是我的代码(注意,我使用的是 dayjs 来格式化)。
let result = transactionData.reduce((acc, {
MaterialID, TransactionDate, TransactionQuantity }) => {
let date = dayjs(TransactionDate).format("MMM-YY");
const _material = (acc[MaterialID] ?? = { monthlyVolume: dateObj });
_material.monthlyVolume[date].sum += parseFloat(TransactionQuantity);
_material.monthlyVolume[date].count++;
return acc;
}, {}
)
这也是我尝试的一个代码笔。
解决方案
1)您使用过
const _material = (acc[MaterialID] ?? = { monthlyVolume: dateObj });
由于中间有空格,这在语法上是不正确的?? =
2)你必须克隆dateObj
为每个创建2个单独的对象MaterialID
function createDateObjClone(obj) {
return Object.keys(obj).reduce((acc, curr) => {
acc[curr] = { ...obj[curr] };
return acc;
}, {});
}
并将其用作
monthlyVolume: { ...createDateObjClone(dateObj) }
你也可以试试我的解决方案
const transactionData = [
{
MaterialID: "3000745",
TransactionQuantity: "2.000",
TransactionDate: "01/15/2020",
},
{
MaterialID: "3000745",
TransactionQuantity: "3.000",
TransactionDate: "2/24/2020",
},
{
MaterialID: "3000051",
TransactionQuantity: "1.000",
TransactionDate: "3/10/2020",
},
{
MaterialID: "3000051",
TransactionQuantity: "1.000",
TransactionDate: "4/01/2020",
},
];
const dateDict = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
const dateObj = {
"Jan-20": { sum: 0, count: 0 },
"Feb-20": { sum: 0, count: 0 },
"Mar-20": { sum: 0, count: 0 },
"Apr-20": { sum: 0, count: 0 },
};
const getMonthObj = (acc, MaterialID, { month, year }) => acc[MaterialID]["monthlyVolume"][`${dateDict[month - 1]}-${year.slice(-2)}`];
function createDateObjClone(obj) {
return Object.keys(obj).reduce((acc, curr) => {
acc[curr] = { ...obj[curr] };
return acc;
}, {});
}
function addData(target, sum) {
target.sum = +sum;
target.count++;
}
const result = transactionData.reduce((acc, curr) => {
const { MaterialID, TransactionQuantity, TransactionDate } = curr;
const [month, , year] = TransactionDate.split("/");
if (!acc[MaterialID])
acc[MaterialID] = { monthlyVolume: { ...createDateObjClone(dateObj) } };
const obj = getMonthObj(acc, MaterialID, { month, year });
if (obj) addData(obj, TransactionQuantity);
return acc;
}, {});
console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
推荐阅读
- javascript - 如果触发条件,我如何隐藏元素?
- javascript - 如何以编程方式格式化开始和结束标签之间的文本,然后删除标签
- python - 如何从 JSON 数据框中仅读取特定列?
- java - 如何从 java.net.HttpClient 请求的响应中获取 http 状态消息
- image-processing - Otsu 算法、Canny 边缘和 HOG 用于文件夹中的多个图像
- django - Django Country State City Chained Dropdown
- amazon-web-services - 普罗米修斯中的警报管理器给出退出代码错误并忽略普罗米修斯中警报管理器的分配
- flutter - Flutter:弹出 2 个警报对话框时应用程序崩溃
- python - 在将数据插入突触表数据类型时自动从 Varchar 转换为 Text
- list - 在列表中使用参数 | 颤振/飞镖