通过键减少转换单个数组
Posted
技术标签:
【中文标题】通过键减少转换单个数组【英文标题】:Transform single an array with reduce by key 【发布时间】:2021-12-30 04:17:03 【问题描述】:我在这里Transform an Array into an Object using .reduce() 提出了类似的问题,但是我正在尝试使用 findIndex 找到替代解决方案。
这个输入数据:
const reports = [
dateOfReport: "11-01-2021",
userId: "id1",
userMetric: first_metric: 10, second_metric: 15 ,
,
dateOfReport: "11-01-2021",
userId: "id2",
userMetric: first_metric: 9, second_metric: 14 ,
,
dateOfReport: "12-01-2021",
userId: "id1",
userMetric: first_metric: 11, second_metric: 14 ,
,
dateOfReport: "12-01-2021",
userId: "id2",
userMetric: first_metric: 16, second_metric: 19 ,
,
];
输出数据必须是:
const output = [
dateOfReport: "11-01-2021",
id1: first_metric: 10, second_metric: 15 ,
id2: first_metric: 9, second_metric: 14 ,
,
dateOfReport: "12-01-2021",
id1: first_metric: 11, second_metric: 14 ,
id2: first_metric: 16, second_metric: 19 ,
,
];
我尝试在下面编写类似的代码,但输出中出现重复数据。谁能帮忙解决这个问题?
const groupedReports = reports.reduce((acc, dataItem) =>
const nodeIndex = acc.findIndex((item) => item.dateOfReport === dataItem.dateOfReport);
const newNode = date: dataItem.date, [dataItem.userId]: dataItem.userMetric ;
console.log("NEW NODE", newNode);
return [...acc.slice(0, nodeIndex - 1), newNode, ...acc.slice(nodeIndex + 1)]
, []);
【问题讨论】:
【参考方案1】:您可以使用一个对象进行分组并将新属性分配给 id。
const
reports = [ dateOfReport: "11-01-2021", userId: "id1", userMetric: first_metric: 10, second_metric: 15 , dateOfReport: "11-01-2021", userId: "id2", userMetric: first_metric: 9, second_metric: 14 , dateOfReport: "12-01-2021", userId: "id1", userMetric: first_metric: 11, second_metric: 14 , dateOfReport: "12-01-2021", userId: "id2", userMetric: first_metric: 16, second_metric: 19 ],
result = Object.values(reports.reduce((r, dateOfReport, userId, userMetric ) =>
(r[dateOfReport] ??= dateOfReport )[userId] = userMetric;
return r;
, ));
console.log(result);
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
//(r[dateOfReport] ??= dateOfReport )[userId] = userMetric;据我了解,此解决方案会改变对象而不是创建新对象 这个属性赋值有什么问题?【参考方案2】:我认为你可以这样做:
reports.reduce((pre, cur) =>
let index = pre.findIndex(item => item.dateOfReport == cur.dateOfReport)
if (index != -1)
pre[index][cur.userId] = cur.userMetric
else
pre.push(
dateOfReport: cur.dateOfReport,
[cur.userId]: cur.userMetric
)
return pre
, [])
【讨论】:
我注意到你的代码使用了slice
,它消耗了太多的性能。【参考方案3】:
这是我的解决方案:
const reports = [
dateOfReport: "11-01-2021",
userId: "id1",
userMetric: first_metric: 10, second_metric: 15 ,
,
dateOfReport: "11-01-2021",
userId: "id2",
userMetric: first_metric: 9, second_metric: 14 ,
,
dateOfReport: "12-01-2021",
userId: "id1",
userMetric: first_metric: 11, second_metric: 14 ,
,
dateOfReport: "12-01-2021",
userId: "id2",
userMetric: first_metric: 16, second_metric: 19 ,
,
];
const sortReports = (reports) =>
// Array of dates with no duplicates
const dates = [...new Set(reports.map(el => el.dateOfReport))];
// Replace each date with an array of reports that are relevant to the date
// Reduce each array of reports into an object with your desired format
const newReports = dates
.map(date => reports
.filter(report => report.dateOfReport === date)
.reduce(el => (
dateOfReport: el.dateOfReport,
[el.userId]: el.userMetric
)));
return newReports;
console.log(sortReports(reports));
【讨论】:
以上是关于通过键减少转换单个数组的主要内容,如果未能解决你的问题,请参考以下文章