js对已选数据进行范围过滤

记录一次 @边城大佬 帮我解决的难题。感谢大佬,以下是大佬的主页,大家可以关注下。
https://segmentfault.com/u/ja...

项目场景:类型包含全年和季节,季节是可以配置的,不管选择年还是季节,都可以新增需求响应数据,弹窗中有两个下拉框,起始时刻和终止时刻,范围是0-23,选择一条信息填写完可以点击保存,点击页面中新增可以打开弹窗重新增加信息
遇到问题:
第一次添加数据:如果起始时间选择3,终止时间选择6进行保存,下次新增时3-6是不能选择,而且新选择的时间范围不能包含3-6,比如新选择的起始时间是1,终止时间是9,因为1-9包含了3-6的部分,所以不能选择,但是0-3可以选择,7-10可以选择。
第二次添加数据:如果起始时间选择9,终止时间选择14进行保存,这时新增的全部数据是:

hasAddData = [
    {startTime: 3, endTime: 6, upValue: 1,downValue: 0.3},
    {startTime: 9, endTime: 14, upValue: 0.5,downValue: 0.8},
]

下次新增时,只能选择的数据列表为: [0,1,2],[7,8],[15,16,17,18,19,20,21,22,23],如果起始时刻选择0,终止时刻只能是0、1或者2,如果起始时刻选择是7,终止时刻只能是8。
以此类推,写出起始时刻的下拉框数据和终止时刻的下拉框数据。
弹窗图示:
js对已选数据进行范围过滤_第1张图片

以下是实现逻辑:

export default {
  name: "addTime",
  props: {
    showAddDialog: {
      type: Object,
      default: () => {},
    },
  },
  data() {
    return {
      formLoading: false,
      timeInfoForm: {
        season: "",
        st: "",
        et: "",
        up: "",
        down: "",
      },
      seasonList: [],
      hasAddData: [], // 已添加数据
    };
  },
  created() {
    // data是父组件传递过来已经添加的数据
    let data = this.$deepClone(this.showAddDialog.data);
    // type---> 1年,2季节
    if (this.showAddDialog.type == 2) {
      // columns是父组件传递过来的季节数据
      this.seasonList = this.showAddDialog.columns;
      this.timeInfoForm.season = this.seasonList[0];
      this.handleDataFormat();
    } else {
      this.hasAddData = data;
    }
  },
  computed: {
    // 获取默认的0-23小时数据
    getAllTimeData() {
      let arr = [];
      for (let i = 0; i <= 23; i++) {
        arr.push(i);
      }
      return arr;
    },
    // 获取起始时刻的数据
    stList() {
      return this.getAllTimeData.filter((t) =>
        this.hasAddData.every(({ st, et }) => t < st || t > et)
      );
    },
    // 获取终止时刻的数据
    etList() {
      let start = this.timeInfoForm.st;
      let startIndex = this.stList.indexOf(start);
      return this.stList.filter(
        (t, i) => t >= start && t - start === i - startIndex
      );
    },
  },
  methods: {
    // 切换起始时间
    handleStartChange() {
      this.timeInfoForm.et = "";
    },
    // 季节格式化数据
    handleDataFormat() {
      let data = this.$deepClone(this.showAddDialog.data);
      // 使用reduce函数,将数据分组
      /**
        let arr = {
          春季: [
            {season: "春季", st: 12, et: 15, up: 0.2, down: 0.4}
            {season: "春季", st: 18, et: 21, up: 1, down: 1}
          ],
          夏季: [
            {season: "夏季", st: 12, et: 15, up: 0.2, down: 0.4}
          ],
          秋季: [],
          冬季: []
        }
     */
      let arr = data.reduce((prev, curr) => {
        let key = curr["season"];
        if (!prev[key]) {
          prev[key] = [];
        }
        prev[key].push(curr);
        return prev;
      }, {});
      // 如果该季节下没有数据,则使用默认的0-23小时数据
      if (!arr[this.timeInfoForm.season]) {
        this.hasAddData = [];
      } else {
        this.hasAddData = arr[this.timeInfoForm.season];
      }
    },
    // 切换季节
    handleSeasonChange(val) {
      this.timeInfoForm.season = val;
      this.handleDataFormat();
    },
  },
};

主要逻辑是计算出起始时刻和终止时刻,脑子中有一些想法,但是代码总是编写有问题,因此记录下大佬的编码,再次感谢边城大佬的帮助。

你可能感兴趣的:(js对已选数据进行范围过滤)