首页 > 其他分享 >JS 通过年份获取月,季度,半年度,年度

JS 通过年份获取月,季度,半年度,年度

时间:2023-10-18 16:23:39浏览次数:29  
标签:arr 年份 console copyArr JS let year 半年度 type

 功能描述:

实例化一个函数,给函数内传递不同的参数,获取从起始年份到现在年度所有的月份,季度,半年度,年度

动态演示

 

 

---------正文代码开始--------

1. 封装函数 createMonth 注:此代码可直接复制黏贴使用

function createMonth() {
  let typeText="";
  let today = new Date();
  // 获取当前的年
  let currentYear = today.getFullYear();
  // 获取当前的月份
  let currentMonth = today.getMonth() + 1;
  // 输出数据
  this.arr = [];
  this.type = "";
  this.year = "";
  this.currentMonth = currentMonth;
  this.currentYear = currentYear;
  
  // 初始化函数,页面进来先调用init函数
  /*
   year: 接收字符串类型的4位数字年份
   type: 1 月度,2 季度,3 半年度,4 年度 
   isCurrentMonth:是否展示当前的月份,季度,半年度,年度
   isCurrentMonth=false 不展示
   isCurrentMonth=true 展示
   
   实例化createMonth函数后, 调用init函数回将生成的数据 return 出去,每次生成新的数据
   */
  this.init = function(year, type,isCurrentMonth=false) {
    this.type = type;
    this.year= year;
    this.arr = [];
    this.isCurrentMonth=isCurrentMonth;
    this.setYear();
    this.setType();
    return this.arr;
  }
  // 处理接受到的type值
  /*
  处理接受到type类型,如果没有值,就赋默认值月即1
  */
  this.setType = function() {
    // type 不存在就赋默认值为4
    let type=this.type || 1;
    if (type == 1) {
      // 月度
      typeText = '月';
      this.setMonthData();
    } else if (type == 2) {
      // 季度
      typeText = '季度';
      this.setQuarterData();
    } else if (type == 3) {
      // 半年度
      typeText = '半年度';
      this.setSemiannualData();
    } else if (type == 4) {
      // 年度
      typeText = '年度';
      this.setYearListData();
    }
  }
  // 处理接受到的年份
  /*
  处理接受到的年份,如果没有值就赋默认值为当前的年
  */
  this.setYear = function() {
    let year=this.year;
    // 判断接收到的年份是否是数值类型
    if (year && Object.prototype.toString.call(year) != "[object Number]") {
      year = Number(year);
    } else if (!year) {
      year = currentYear;
    }
    this.year = year;
  }
  
  // 去重 数组对象去重
  this.removeDuplicateObjects=function (array,label) {
    const obj = {};
    let arr=[];
    arr = array.reduce((total, next) => {
      let key=next[label]
      if(key){
        obj[key] ? '' : obj[key] = true && total.push(next)
        return total
      }
    }, []);
    return arr;
  }
  // 排序  数组属性值相同的排列到一起
  this.setArrSort = function(dataArr) {
    dataArr = JSON.parse(JSON.stringify(dataArr));
    return dataArr.sort((a, b) => {
      if ((a['year'].toString()) != (b['year'].toString())) {
        return (a['year'].toString()).localeCompare(b['year'].toString());
      }
    })
  }
  // 设置年度
  this.setYearListData = function() {
    // console.log('设置年度');
    // 设置当前年的年数据
    if (this.year == currentYear) {
      let obj = {
        year: this.year,
        val: 1,
        type: this.type,
        typeText: '年度',
        label: this.year + '年'
      }
      this.arr.push(obj);
    } else if (this.year < currentYear) {
      // 设置小于当前年的年数据
      for (let i = this.year; i <= currentYear; i++) {
        let obj = {
          year: i,
          val: 1,
          type: this.type,
          typeText: '年度',
          label: i + '年'
        }
        this.arr.push(obj);
      }
      // 是否过滤掉当前的年
      if(this.isCurrentMonth==false && this.type==4){
        this.arr.forEach((item,index,arr)=>{
          // 过滤掉当前的年
          if(item.year==currentYear){
            this.arr.splice(index,1);
          }
        });
        
      }
    }
  }
  // 设置半年度
  // 此处调用的年度来生成半年度
  this.setSemiannualData = function() {
    // console.log('设置半年度');
    // 调用年数据,用以生成上半年和下半年
      this.setYearListData();
      // 此处用了深拷贝,如若不使用深拷贝,copyArr最后的数据无法改变
      let copyArr = JSON.parse(JSON.stringify(this.arr));
      // 因为是上半年,下半年,所以使用了数据拼接,将原有数据再次拼接一次
      copyArr = copyArr.concat(this.arr);
      // 数据排序,将相同年份的数据放到一起
      let sortArr = this.setArrSort(copyArr);
      // 需要删除下标
      let deleteIndex=null;
      // 数据排序后重新赋值
      copyArr = sortArr;
      // 用以标注上半年,下半年; 1上半年,2下半年
      let val = 1;
      let label = "上半年"
      for (let i = 0; i < copyArr.length; i++) {
        // 当前月份大于6就是上半年
        if (currentMonth > 6 && (i % 2 == 0)) {
          val = 1;
          // 当前月份在6-12就是下半年
        } else if (currentMonth > 6 && currentMonth < 12 && (i % 2 != 0)) {
          val = 2;
        }
        
        label = val == 1 ? '上半年' : '下半年';
        copyArr[i].val = val;
        copyArr[i].typeText = label;
        copyArr[i].label = copyArr[i].year + '年' + label;
        // 获取当前年的下半年下标
        if(copyArr[i].year == currentYear && copyArr[i].val==2){
          deleteIndex=i;
        }
      }
      // 是否过滤掉当前年度下半年
      if(this.isCurrentMonth==false){
        // 移除当前年的下半年
        copyArr.splice(deleteIndex,1);
      }
      this.arr = copyArr;
    
  }
  // 设置季度
  // setQuarterData函数是通过月度来生成季度的
  this.setQuarterData = function() {
    // console.log('设置季度');
    // 调用月度
    this.setMonthData();
    let arr = [];
    let copyArr = JSON.parse(JSON.stringify(this.arr));
    copyArr = copyArr.map((item, i, arr) => {
      // 使用月份除以3向上取整,获取到是第几季度
      let val = Math.ceil(item.val / 3);
      item.val = val;
      item.label=item.year+'年'+item.val+'季度'
      return item;
    });
    // 因为调用了生成的月份,因此要过滤掉相同的数据
    arr=this.removeDuplicateObjects(copyArr,'label');
    this.arr = arr;
  }
  // 设置月度
  this.setMonthData = function() {
    // console.log('设置月度');
    // 调用年度
    this.setYearListData();
    let arr = [];
    let copyArr = JSON.parse(JSON.stringify(this.arr));
    // 最大月份
    let maxMonth = currentMonth;
    // 需要删除的数据下标
    let deleteIndex=null;
    for (let i = 0; i < copyArr.length; i++) {
      // 如果年份小于当前的年,最大月份赋值12,如果如果年份等于当前的年,最大月份就是当前月份
      if (copyArr[i].year < currentYear) {
        maxMonth = 12;
      } else if (copyArr[i].year == currentYear) {
        maxMonth = currentMonth;
      }
      for (let m = 1; m <= maxMonth; m++) {
        let obj = {
          year: copyArr[i].year,
          val: m,
          type: this.type,
          typeText: typeText,
          label: copyArr[i].year + '年' + m + '月'
        }
        /*
         过滤当前月份
         获取当前月份的下标, 用于删除当前的月份
         考虑到性能问题  所以注释掉了
        */
        // if (copyArr[i].year == currentYear && m==currentMonth) {
        //   deleteIndex=m;
        // }
        arr.push(obj);
      }
    }
    // 是否过滤当前月份
    if(this.isCurrentMonth==false){
      // arr.splice(deleteIndex,1)
      arr = arr.filter(function(item) {
        if (item.year == currentYear) {
          // 移除当前的月
          return item.val !== currentMonth;
        } else {
          return item;
        }
      });
    }
    this.arr = arr;
  }
}

 

2. 函数解释说明

使用一下函数之前,需要先实例化createMonth函数为对象,具体看以下步骤三

2.1. this.init  初始化函数

2.11.   createMonth 实例化完成后,需要调用此函数来调用实例化函数内部其他数,给一些关键性数据赋值,并且回把生成好的数据return出去

2.12. init  函数接收三个参数  year,type,isCurrentMonth

year: 接收字符串类型的4位数字年份

type: 1 月度,2 季度,3 半年度,4 年度 

isCurrentMonth:true/false 是否展示当前的月份,季度,半年度,年度

isCurrentMonth:true 展示

isCurrentMonth:false 不展示,默认是false

当值是 false  时,使用了JS的 splice  移除了当前年,月,季度,和当前年的下半年

2.2 this.setType    处理接受到的type值,类型为数值类型

处理接受到type类型,如果没有值,就赋默认值月即1

2.3 this.setYear

处理接受到的年份,如果没有值就赋默认值为当前的年

2.4 this.removeDuplicateObjects

2.4.1. 去重 数组对象去重,在网找的方法,自己做了稍加修改

接收两个参数:array,label

array 数组对象

label 对象中过滤的key名称

2.5 this.setArrSort 排序  数组属性值相同的排列到一起

2.6 this.setYearListData  生成年数据

在生成半年度,月度数据时候,也调用了setYearListData 该函数

2.7 this.setSemiannualData    生成半年度数据

该函数里面调用了年函数setYearListData,使用深拷贝,生成了双份数据

2.8 this.setQuarterData  生成季度数据

该函数里面调用了月函数setMonthData来生成季度,通过月份除以三向上取整,获取到是第几季度

因为调用了月份函数setMonthData,导致生成的季度产生了重复数据,就是用了 removeDuplicateObjects 函数去重

2.9 this.setMonthData  生成月度数据

该函数里面调用了年函数setYearListData,用于生成对应年的月份

3. 函数调用-通过控制台查看

// 实例化 createMonth 函数 为一个对象
var start = new createMonth();
console.log("打印实例:",start);
// 调用实例化函数中的init函数传参,false 不展示当前月,季度,半年度,年
let arr1=start.init('2023', '1' ,false);
// 调用实例化函数中的init函数传参,true 展示当前月,季度,半年度,年
let arr2=start.init('2023', '1' ,true);
console.log("原始arr",start.arr);
console.log('arr1:',arr1);
console.log('arr2:',arr2);

 

--------正文代码结束--------

4. 函数调用-通过UI页面查看,如果上面正文已经理解,可以忽略以下UI页面演示

4.1 演出页面引用了layui,演示代码可以直接使用

4.2  引入layui依赖

// 引入layui依赖
<!-- 引入 layui.css -->
<link rel="stylesheet" href="//unpkg.com/[email protected]/dist/css/layui.css">
 
<!-- 引入 layui.js -->
<script src="//unpkg.com/[email protected]/dist/layui.js"></script>

 

4.2 演示使用的 HTML代码

<form class="layui-form layui-form-pane" action="">
  <div class="layui-form-item" pane>
    <label class="layui-form-label">选择年份</label>
    <div class="layui-input-inline">
      <input type="text" class="layui-input" id="test1">
    </div>
  </div>
   <div class="layui-form-item">
    <label class="layui-form-label">选择类别</label>
    <div class="layui-input-block">
      <input type="radio" name="sex" value="1" title="月度" lay-filter="demo-radio">
      <input type="radio" name="sex" value="2" title="季度" lay-filter="demo-radio">
      <input type="radio" name="sex" value="3" title="半年度" lay-filter="demo-radio">
      <input type="radio" name="sex" value="4" title="年度" lay-filter="demo-radio">
    </div>
  </div>
  <div class="layui-form-item" pane>
    <label class="layui-form-label">是否开启</label>
    <div class="layui-input-block">
      <input type="checkbox" value="false" lay-skin="switch" lay-filter="demo-checkbox-switch" lay-text="开启|关闭">
      <div class="layui-bg-orange">是否展示当前的月份,季度,半年度,年度</div>
    </div>
  </div>
</form>
<!-- 展示数据到页面上 -->
<table id="tableDemo" lay-filter="tableDemo"></table>

 

4.3 演示使用的相关JS代码

var start = new createMonth();
let selectYear="",selectType="",isCurrentMonth=false;
let dataArr=[];
layui.use(['laydate','form','table'], function(){
  var laydate = layui.laydate;
  var form = layui.form;
  var table = layui.table;
  var tableReload = table.reload;
  var $ = layui.$;
  // 日期触发函数
  laydate.render({
    elem: '#test1' ,//指定元素
    type: 'year',
    format: 'yyyy' ,//可任意组合
   done: function(value, date, endDate){
      //得到日期生成的值,如:2017-08-18
      // console.log(value);
      selectYear=value;
      dataArr = start.init(selectYear,selectType,isCurrentMonth);
      console.log(dataArr);
      createTable();
      //得到日期时间对象:{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}
      // console.log(date);
    }
  });
  // 监听单选框
  form.on('radio(demo-radio)', function(data){
    // console.log(data.elem); //得到radio原始DOM对象
    // console.log(data.value); //被点击的radio的value值
    selectType=data.value;
    dataArr = start.init(selectYear,selectType,isCurrentMonth);
    console.log(dataArr);
    createTable();
  });  
  // 监听开关
  form.on('switch(demo-checkbox-switch)', function(data){
    // console.log(data.elem); //得到checkbox原始DOM对象
    // console.log(data.elem.checked); //开关是否开启,true或者false
    isCurrentMonth=data.elem.checked;
    dataArr = start.init(selectYear,selectType,isCurrentMonth);
    console.log(dataArr);
    createTable();
    // console.log(data.value); //开关value值,也可以通过data.elem.value得到
    // console.log(data.othis); //得到美化后的DOM对象
  });
  ;
});
​
function createTable(){
  layui.use('table', function(){
    var table = layui.table;
    table.render({
      elem: '#tableDemo'
      ,id:"demoReload"
      ,height: 600
      ,page:true
      ,limit:12
      ,data:dataArr
      ,parseData: function(res){ //res 即为原始返回的数据
        console.log(res);
      }
      ,cols: [[ //表头
        {field: 'label', title: '名称', sort: true, fixed: 'left'}
        ,{field: 'year', title: '年份', sort: true}
        ,{field: 'typeText', title: '类型'}
        ,{field: 'val', title: 'val值'} 
        ,{field: 'type', title: 'type值'} 
      ]]
    })
  })
}

 

 

 

 

 

 

 

 

 

 


标签:arr,年份,console,copyArr,JS,let,year,半年度,type
From: https://www.cnblogs.com/ts119/p/17772640.html

相关文章

  • JS数组对象合并,a,b 合并为c
    vara=[{id:2,nickname:"韩信",checked:false},{id:7,nickname:"刘邦",checked:true},];varb=[{id:2,nickname:"韩信",checked:false},{id:7,nickname:"刘邦",checked:false},{id:8,nickname:&......
  • keydb 6.3.3 modjs docker 镜像
    keydb6.3.3已经发布一段时间了,但是ModJS的支持镜像一直还没有提供,就基于现有的基础镜像搞了一个方便学习使用Dockerfile FROMeqalpha/modjsasbase FROMeqalpha/keydb:latestRUNmkdir-p/usr/lib/keydb/modules#Copyoverprecompiledubuntu1......
  • js中数组的各种遍历方式
    一、ES5中数组遍历方式letarr=[1,2,3,2,4]1、for循环for(leti=0;i<arr.length;i++){console.log(arr[i])}//123242、forEach():没有返回值,调用数组的每个元素,并将元素传递给回调函数。//参数:item(必需)->当前元素//index(可选)->......
  • JsonPath使用(Java)
    JsonPath使用(Java)Java有一些类似于jq的语法库和工具。其中一个叫做JsonPath,它允许使用类似于jq的语法来查询和操作JSON数据。可以使用JsonPath来提取特定的JSON字段、过滤数据、执行计算等操作。另外,还有一些其他的Java库和框架也提供了类似的功能,比如FastJson,Gson和Jackson。这......
  • 直播软件搭建,利用原生JS实现回到顶部以及吸顶效果
    直播软件搭建,利用原生JS实现回到顶部以及吸顶效果  <style>    .box1{      width:1200px;      height:800px;            margin:0auto;    }    .box2{      width:1200px; ......
  • cube.js oracle 新版本npm 包支持
    cube.js目前来说是越来越复杂了(不是代码多复杂,而且融合了不少三方语言,python,rust,nodeaddonjava)如果网络不是很好的情况下编译cube.js是极其痛苦的,而且不少依赖问题,cube.js实际上很早就支持oracle,但是今天oracle比较给力提供了基于node的原生实现这样node系统集成......
  • Node.js 21 版本已发布!
    本文翻译自Node.js21isnowavailable!,来源:TheNode.jsProject,略有删改。我们很高兴地宣布Node.js21的发布!亮点包括V8JavaScript引擎更新到11.8,稳定fetch和WebStreams,一个新的实验性标志来切换模块默认值(--experimental-default-type),一个内置的WebSocket客户端,我们的测......
  • 用jstack导出线程信息,用jmap导出线程信息和堆数据信息
    jmap导出的*.hprof文件需要用jvisualvm.exe工具来查看(当然也有第三方的其他工具),jdk8之后的是不会自带了需要手动安装;jmap导出的文件里是包含了线程信息,但是没有jstack导出的多,比如jstack里还有具体等待哪个锁的信息,这个锁的对象类型,还能看到是哪个线程获得了这个锁locked;jmap使......
  • react 公司项目学习 【react+webpack+nw.js + mobx+react-intl 实现的多页面多语言win
    这几天突然要来个react项目;听说还比较复杂;项目组内就两个人会react还在忙,整组主要是用vue;这不,这种‘狗都不干’的事,被安排到我身上了,那就学吧;一、研究代码结构不得不说,这目录结构搞得有点复杂,算是我接触中除了乾坤和electron之外,相当复杂的了,慢慢阅读吧;看懂了,原来是react+web......
  • Node.js框架:通过nvm实现多个node版本共存使用
    一、环境部署1、nvm下载下载地址:https://github.com/coreybutler/nvm-windows/releases2、nvm安装打开安装程序后按流程走就行,中间的安装地址可以自定义调整。注:在选择node.js的路径时,默认路径为C盘里的安装路径,如果本地在该路径下已经安装过......