封装单位转换的通用方法

174 阅读2分钟

在某些场景下我们需要将不同单位的数据进行转换,然后来处理。这时我们就可以封装一个通用的方法。

代码实现

/**
 * unitList 转换单位的信息列表
 * originData 源数据
 * targetUnit 转换的目标单位
 * handleFn 转化后数据的处理方法
 */
export default function unitUnionHandle(params) {
  const { unitList, originData, targetUnit, handleFn } = params;
  if (!unitList || unitList.length === 0) {
    alert("请传入单位列表信息");
    return;
  }
  if (!originData) {
    alert("请传入数据");
    return;
  }
  // 设置默认单位
  const defaultUnit = Object.keys(unitList)[0];

  // 获取格式化后的数据
  let formatedData = [];
  const unitKeyList = Object.keys(unitList);
  originData.forEach((i) => {
    formatedData.push(formatUnit(i, unitKeyList));
  });

  // 统计重复的单位及重复次数
  const countObj = formatedData.reduce((acc, curr) => {
    if (acc[curr.unit]) {
      acc[curr.unit]++;
    } else {
      acc[curr.unit] = 1;
    }
    return acc;
  }, {});

  let targetData = [],
    unionUnit = "";
  // 所有数据单位相同时
  if (Object.keys(countObj).length === 1) {
    unionUnit = (targetUnit || Object.keys(countObj)[0])
  } else {
    // 有不重复的单位时
    unionUnit = (targetUnit || defaultUnit)
  }
  formatedData.forEach((i) => {
    targetData.push(calculate(i, unionUnit, unitList));
  });

  // 调用转化后的数据处理函数
  handleFn({ targetData, unionUnit });
}

// 将数据中的数值与单位分割开(格式化方式待优化)
// 不同单位如果有相同字符如何处理?
function formatUnit(data, units) {
  let size, unit;
  units.forEach((i) => {
    if (data.indexOf(i) !== -1) {
      size = data.slice(0, data.indexOf(i));
      unit = data.slice(data.indexOf(i));
    }
  });
  return { size, unit };
}

// 单位转换的计算方式
function calculate(curData, unionUnit, unitList) {
  const { size, unit } = curData;
  const curUnitValue = unitList[unit].value;
  const unionUnitValue = unitList[unionUnit].value;
  let finalSize = size - 0;
  if (curUnitValue >= unionUnitValue) {
    for (let i = curUnitValue; i > unionUnitValue; i--) {
      for (const key in unitList) {
        if (unitList[key].value === i) {
          finalSize *= unitList[key].nextStep;
        }
      }
    }
  } else {
    for (let i = unionUnitValue; i > curUnitValue; i--) {
      for (const key in unitList) {
        if (unitList[key].value === i) {
          finalSize /= unitList[key].nextStep;
        }
      }
    }
  }
  return finalSize;
}

方法调用

// 导入方法
import unitUnionHandle from "./components/utils";

// 定义数据
data() {
    return {
      // 参与转换的单位列表
      units: {
        SS: {
          value: 1,
          nextStep: 0,
        },
        MM: {
          value: 2,
          nextStep: 60,
        },
        HH: {
          value: 3,
          nextStep: 60,
        },
        D: {
          value: 4,
          nextStep: 24,
        },
        M: {
          value: 5,
          nextStep: 30,
        },
        Y: {
          value: 6,
          nextStep: 12,
        },
      },
      baseData: ["10Y", "10M", "10D", "10HH", "12MM", "7200SS"],
    };
  },

// 使用
unitUnionHandle({
  unitList: this.units,
  bd: this.baseData,
  targetUnit: "HH",
  handleFn(obj) {
    const { data, unionUnit } = obj;
    console.log(data, unionUnit);
  },
});      

说明

  1. 单位列表及计算公式需根据不同场景单独维护;

  2. 计算公式重复代码较多,需优化;

  3. 将数值与单位分割的方法存在局限性,不适用于所有场景下;

  4. 存在所有数据单位相同的情况,判断是否重复的方式有很多,此处采取 reduce 的方法,是为了获取到重复的单位及重复次数,便于后续拓展;