如何将 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; }