如何将 DRY 的概念应用于重复的数组映射任务?
How would one apply the concept of DRY for repetitive array mapping tasks?
给定以下代码...
// last 7 days data from db ...
let last7Days =
result.map((data) => data._id).slice(1).slice(-7);
let last7daysIncome =
result.map((data) => data.totalIncomeAmount).slice(1).slice(-7);
let last7daysAvgIncome =
result.map((data)=> data.avrageIncome).slice(1).slice(-7);
let last7daysPatientionsCount =
result.map((data)=> data.PatientionsCount).slice(1).slice(-7);
let last7disease =
result.map((data)=>data.diseaseArr).slice(1).slice(-7);
...如何使用 DRY 概念 简化此代码(D而不是 Repeat Yourself) in JavaScript?
创建一个函数,传入要提取的字段的参数,甚至要回溯的天数:
function lastDays(result, field, days) {
return result.slice(days).map((data)=>data[field]);
}
function lastSevenDays(result, field) {
return lastDays(result, field, -7);
}
let last7Days = lastSevenDays(result, "_id")
let last7daysIncome = lastSevenDays(result, "totalIncomeAmount")
let last7daysAvgIncome =lastSevenDays(result, "avrageIncome")
let last7daysPatientionsCount = lastSevenDays(result, "PatientionsCount")
let last7disease = lastSevenDays(result, "diseaseArr")
由于 OP 显然映射了 5 次数据项数组,每次收集此类项目的另一个特定 属性 值,因此可以想出一种方法来解决合并和收集项目条目的问题通用方式(与底层数据结构无关)。
将数组项合并到分组数组的对象中是一项经典的 reduce
任务,使用下一个提供的解决方案(由于其通用实现)需要完成两次。
以下实现还使用 Object.entries
in order to access each entry's key-value pair directly. It also utilizes the Logical nullish assignment / ??=
运算符来访问或 create/assign 一行代码的数组。
function mergeAndCollectItemEntries(result, item) {
return Object
.entries(item)
.reduce((merger, [key, value]) => {
(merger[key] ??= []).push(value);
return merger;
}, result);
}
const sampleData = [
{ _id: 'foo', totalIncomeAmount: 10_000, last7daysAvgIncome: 2_500, PatientionsCount: 123, diseaseArr: ['long', 'sick', 'leave'] },
{ _id: 'bar', totalIncomeAmount: 8_000, last7daysAvgIncome: 2_000, PatientionsCount: 99, diseaseArr: ['very', 'long', 'sick', 'leave'] },
{ _id: 'baz', totalIncomeAmount: 4_000, last7daysAvgIncome: 1_000, PatientionsCount: 50, diseaseArr: ['really', 'long', 'sick', 'leave'] },
];
const {
_id: last7Days,
totalIncomeAmount: last7daysIncome,
last7daysAvgIncome: avrageIncome,
PatientionsCount: last7daysPatientionsCount,
diseaseArr: last7disease,
} = sampleData.slice(-7).reduce(mergeAndCollectItemEntries, {});
console.log({
last7Days,
last7daysIncome,
avrageIncome,
last7daysPatientionsCount,
last7disease,
} );
// was before ...
//
// // last 7 days data from db...
//
// let last7Days =
// result.map((data)=>data._id).slice(1).slice(-7);
//
// let last7daysIncome =
// result.map((data) => data.totalIncomeAmount).slice(1).slice(-7);
//
// let last7daysAvgIncome =
// result.map((data)=> data.avrageIncome).slice(1).slice(-7);
//
// let last7daysPatientionsCount =
// result.map((data)=> data.PatientionsCount).slice(1).slice(-7);
//
// let last7disease =
// result.map((data)=>data.diseaseArr).slice(1).slice(-7);
.as-console-wrapper { min-height: 100%!important; top: 0; }
给定以下代码...
// last 7 days data from db ...
let last7Days =
result.map((data) => data._id).slice(1).slice(-7);
let last7daysIncome =
result.map((data) => data.totalIncomeAmount).slice(1).slice(-7);
let last7daysAvgIncome =
result.map((data)=> data.avrageIncome).slice(1).slice(-7);
let last7daysPatientionsCount =
result.map((data)=> data.PatientionsCount).slice(1).slice(-7);
let last7disease =
result.map((data)=>data.diseaseArr).slice(1).slice(-7);
...如何使用 DRY 概念 简化此代码(D而不是 Repeat Yourself) in JavaScript?
创建一个函数,传入要提取的字段的参数,甚至要回溯的天数:
function lastDays(result, field, days) {
return result.slice(days).map((data)=>data[field]);
}
function lastSevenDays(result, field) {
return lastDays(result, field, -7);
}
let last7Days = lastSevenDays(result, "_id")
let last7daysIncome = lastSevenDays(result, "totalIncomeAmount")
let last7daysAvgIncome =lastSevenDays(result, "avrageIncome")
let last7daysPatientionsCount = lastSevenDays(result, "PatientionsCount")
let last7disease = lastSevenDays(result, "diseaseArr")
由于 OP 显然映射了 5 次数据项数组,每次收集此类项目的另一个特定 属性 值,因此可以想出一种方法来解决合并和收集项目条目的问题通用方式(与底层数据结构无关)。
将数组项合并到分组数组的对象中是一项经典的 reduce
任务,使用下一个提供的解决方案(由于其通用实现)需要完成两次。
以下实现还使用 Object.entries
in order to access each entry's key-value pair directly. It also utilizes the Logical nullish assignment / ??=
运算符来访问或 create/assign 一行代码的数组。
function mergeAndCollectItemEntries(result, item) {
return Object
.entries(item)
.reduce((merger, [key, value]) => {
(merger[key] ??= []).push(value);
return merger;
}, result);
}
const sampleData = [
{ _id: 'foo', totalIncomeAmount: 10_000, last7daysAvgIncome: 2_500, PatientionsCount: 123, diseaseArr: ['long', 'sick', 'leave'] },
{ _id: 'bar', totalIncomeAmount: 8_000, last7daysAvgIncome: 2_000, PatientionsCount: 99, diseaseArr: ['very', 'long', 'sick', 'leave'] },
{ _id: 'baz', totalIncomeAmount: 4_000, last7daysAvgIncome: 1_000, PatientionsCount: 50, diseaseArr: ['really', 'long', 'sick', 'leave'] },
];
const {
_id: last7Days,
totalIncomeAmount: last7daysIncome,
last7daysAvgIncome: avrageIncome,
PatientionsCount: last7daysPatientionsCount,
diseaseArr: last7disease,
} = sampleData.slice(-7).reduce(mergeAndCollectItemEntries, {});
console.log({
last7Days,
last7daysIncome,
avrageIncome,
last7daysPatientionsCount,
last7disease,
} );
// was before ...
//
// // last 7 days data from db...
//
// let last7Days =
// result.map((data)=>data._id).slice(1).slice(-7);
//
// let last7daysIncome =
// result.map((data) => data.totalIncomeAmount).slice(1).slice(-7);
//
// let last7daysAvgIncome =
// result.map((data)=> data.avrageIncome).slice(1).slice(-7);
//
// let last7daysPatientionsCount =
// result.map((data)=> data.PatientionsCount).slice(1).slice(-7);
//
// let last7disease =
// result.map((data)=>data.diseaseArr).slice(1).slice(-7);
.as-console-wrapper { min-height: 100%!important; top: 0; }