antd table合并复杂单元格、分组合并行、分组合并列、动态渲染列、嵌套表头

news2024/10/12 22:22:50

项目里遇到个需求,涉及到比较复杂的单元格合并 、嵌套表头、分组合并行、合并列等,并且数据列还是动态的,效果图如下:
在这里插入图片描述

在这里插入图片描述

可以分组设置【显示列】例如:当前组为【合同约定】,显示列为【合同节点】和【节点金额】

我们按【数据源】进行分组后,把第一组编号为【0001】的单元行合并 ,然后再插入一行【小计】,根据显示的【列数】决定合并几个【单元格】,比如我们的需求可以设置为当【合同节点】与【金额】全部显示时,显示【小计】的信息,再进行单元格合并

我们的数据源如下:

动态列数据

const mockRowData = [
  // {
  //     name: '合同约定',
  //     key: 'agree',
  //     handle: 'lt',
  //     handleValue: 2312313,
  //     color: '#FF811A',
  //     enable: true,
  //     checked: true,
  //     // disabled: true,
  //     checkable: false,
  //     hidden: true,
  //     children: [
  {
    name: '合同节点',
    key: 'contractNodes',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: true,
    checked: true,
    type: 1,
  },
  {
    name: '金额',
    key: 'Money',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: true,
    checked: true,
    type: 1,
  },
  {
    name: '节点比例',
    key: 'NodeRatio',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: false,
    checked: true,
    type: 1,
  },
  {
    name: '付款条件',
    key: 'paymentTerms',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: true,
    checked: true,
    type: 1,
  },
  //     ],
  // },
  // {
  //     name: '确认收入',
  //     key: 'confirmIncome',
  //     handle: 'lt',
  //     handleValue: 2312313,
  //     color: '#FF811A',
  //     enable: false,
  //     checked: true,
  //     // disabled: true,
  //     checkable: false,
  //     hidden: true,
  //     children: [
  {
    name: '成果提交日期',
    key: 'submissionDate',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: false,
    checked: true,
    type: 2,
  },
  {
    name: '证明文件日期',
    key: 'fileDate',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: true,
    checked: true,
    type: 2,
  },
  {
    name: '确认收入',
    key: 'Income',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: false,
    checked: true,
    type: 2,
  },
  {
    name: '确认比例',
    key: 'confirmationRatio',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: false,
    checked: true,
    type: 2,
  },
  //     ],
  // },
  // {
  //     name: '收款',
  //     key: 'receivePayment',
  //     handle: 'lt',
  //     handleValue: 2312313,
  //     color: '#FF811A',
  //     enable: false,
  //     checked: true,
  //     // disabled: true,
  //     checkable: false,
  //     hidden: true,
  //     children: [
  {
    name: '到账日期',
    key: 'DateofReceipt',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: false,
    checked: true,
    type: 3,
  },
  {
    name: '金额',
    key: 'Money1',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: true,
    checked: true,
    type: 3,
  },
  {
    name: '确认比例',
    key: 'confirmationRatio1',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: false,
    checked: true,
    type: 3,
  },
  //     ],
  // },
  {
    name: '应收款',
    key: 'receivables',
    handle: 'lt',
    handleValue: 2312313,
    color: '#FF811A',
    enable: false,
    checked: true,
    children: [],
    type: 4,
  },
];

数据源:

const mockTableData = {
  group1: [
    {
      group: 'group1',
      id: 1,
      name: '第一建筑设计院',
      order: '0001',
      type: '外部承包',
      isConsortium: '是',
      nameSquare:
        'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',
      cstatus: '执行中',
      money: '60,0000,0000',
      value1: 12345,
      contractNodes: 12345,
      Money: 12345,
      NodeRatio: 12345,
      paymentTerms: 12345,
      confirmIncome: 12345,
      submissionDate: 12345,
      fileDate: 12345,
      Income: 12345,
      confirmationRatio: 12345,
      Money1: 879,
      DateofReceipt: '2024-10-25',
      confirmationRatio1: '20%',
      receivables: '',
      agree: '',
      receivePayment: '200,0000,0000',
    },
    {
      group: 'group1',

      id: 2,
      name: '第二建筑设计院',
      order: '0001',
      type: '外部承包',
      isConsortium: '是',
      nameSquare:
        'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',
      cstatus: '执行中',
      money: '60,0000,0000',
      value1: 1234124,
      contractNodes: 1234124,
      Money: 1234124,
      NodeRatio: 1234124,
      paymentTerms: 1234124,
      confirmIncome: 1234124,
      submissionDate: 1234124,
      fileDate: 1234124,
      Income: 1234124,
      confirmationRatio: 1234124,
      Money1: 879,
      DateofReceipt: '2024-10-25',
      confirmationRatio1: '20%',
      receivables: '',
      agree: '',
      receivePayment: '200,0000,0000',
    },
    {
      group: 'group1',

      id: 3,
      name: '第三建筑设计院',
      order: '0001',
      type: '外部承包',
      isConsortium: '是',
      nameSquare:
        'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',
      cstatus: '执行中',
      money: '60,0000,0000',
      value1: 54321,
      contractNodes: 54321,
      Money: 54321,
      NodeRatio: 54321,
      paymentTerms: 54321,
      confirmIncome: 54321,
      submissionDate: 54321,
      fileDate: 54321,
      Income: 54321,
      confirmationRatio: 54321,
      Money1: 879,
      DateofReceipt: '2024-10-25',
      confirmationRatio1: '20%',
      receivables: '',
      agree: '',
      receivePayment: '200,0000,0000',
    },
  ],
  group2: [
    {
      group: 'group2',

      id: 4,
      name: '第一建筑设计院',
      order: '0002',
      type: '外部承包',
      isConsortium: '是',
      nameSquare:
        'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',
      cstatus: '执行中',
      money: '60,0000,0000',
      value1: 12345,
      contractNodes: 12345,
      Money: 12345,
      NodeRatio: 12345,
      paymentTerms: 12345,
      confirmIncome: 12345,
      submissionDate: 12345,
      fileDate: 12345,
      Income: 12345,
      confirmationRatio: 12345,
      Money1: 879,
      DateofReceipt: '2024-10-25',
      confirmationRatio1: '20%',
      receivables: '',
      agree: '',
      receivePayment: '200,0000,0000',
    },
    {
      group: 'group2',

      id: 5,
      name: '第二建筑设计院',
      order: '0002',
      type: '外部承包',
      isConsortium: '是',
      nameSquare:
        'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',
      cstatus: '执行中',
      money: '60,0000,0000',
      value1: 1234124,
      contractNodes: 1234124,
      Money: 1234124,
      NodeRatio: 1234124,
      paymentTerms: 1234124,
      confirmIncome: 1234124,
      submissionDate: 1234124,
      fileDate: 1234124,
      Income: 1234124,
      confirmationRatio: 1234124,
      Money1: 879,
      DateofReceipt: '2024-10-25',
      confirmationRatio1: '20%',
      receivables: '',
      agree: '',
      receivePayment: '200,0000,0000',
    },
    {
      group: 'group2',

      id: 6,
      name: '第三建筑设计院',
      order: '0002',
      type: '外部承包',
      isConsortium: '是',
      nameSquare:
        'XXXXX有限公司公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称公司名称',
      cstatus: '执行中',
      money: '60,0000,0000',
      value1: 54321,
      contractNodes: 54321,
      Money: 54321,
      NodeRatio: 54321,
      paymentTerms: 54321,
      confirmIncome: 54321,
      submissionDate: 54321,
      fileDate: 54321,
      Income: 54321,
      confirmationRatio: 54321,
      Money1: 879,
      DateofReceipt: '2024-10-25',
      confirmationRatio1: '20%',
      receivables: '',
      agree: '',
      receivePayment: '200,0000,0000',
    },
  ],
};

那接下来咱们就先看如何显示【动态列】吧~

1.显示动态列

 const columns = useCallback(() => {
    if (rowData && rowData.length) {
      console.log(rowData);
      const list = [
      // 先写入非动态列
        {
          title: '合同编号',
          dataIndex: 'order',
          width: 50,
          render: (text) => {
            return (
              <div
                className="ellipsis-item"
                title={text}
                style={{ width: '100px' }}
              >
                {text}
              </div>
            );
          },
          onCell: mergeRow,
        },
   		// 循环动态列,
        {
          title: '收款',
          className: 'type3Column',
          children: [
            ...flattenData(rowData, 0)
              .filter((item) => item.checked)
              .filter((item) => item.type === 3)
              .map((item) => {
                return {
                  title: (
                    <div className="ellipsis-item" title={item.name}>
                      {item.name}
                    </div>
                  ),
                  dataIndex: item.key,
                  className: 'type3Column',
                  width: 100,
              render: (text) => {
                return (
                  <div
                    style={{
                      background: getColumnColor(
                        item.enable,
                        text,
                        item.handle,
                        item.handleValue,
                        item.color,
                      ),
                    }}
                    className="value-item"
                  >
                    {text}
                  </div>
                );
              },
                };
              }),
          ],
        },
    
      ];
      console.log('list', list);
      return list;
    }
  }, [rowData]);

2.合并列

思路

我们的列是动态变换的,所以合并的列数也是动态合并的,那我们就需要在每次变化的时候再去判断需要合并几列

1.先将【原始数据源】分组处理,计算每组的【小计】金额 ,然后写入【表格数据源】里
2.循环动态列,将列也分别写入三个数组里
3.判断我们【每组】【动态列】中是否符合我们的需求,是否要显示【小计】信息,设置【要合并的列】为1
4.如果存在,判断本组有无其他列显示,有的话【要合并的列数+1】

处理列数&计算要合并的列数
  const handleColumnData = (row) => {
    console.log('row=======', row);
    let type1list = [];// 分组列1
      let type2list = []; // 分组列2
      let type3list = []; // 分组列3
    let haveAgreeTotal = false;  // 分组列1是否有【小计】
      let haveIncomeTotal = false;  // 分组列1是否有【小计】
      let haveReciveTotal = false;  // 分组列1是否有【小计】
    let AgreeColspan = 0;  // 分组列1要合并的列数
      let IncomeColspan = 0;  // 分组列1要合并的列数
      let ReciveColspan = 0;  // 分组列1要合并的列数

    row.forEach((item) => {
      if (item.type === 1) {
        type1list.push(item.key);
      } else if (item.type === 2) {
        type2list.push(item.key);
      } else if (item.type === 3) {
        type3list.push(item.key);
      }
    });
    // console.log('type1', type1list)
    // console.log('type2', type2list)
    // console.log('type3', type3list)

    if (type1list.length > 0) {
      // 如果同时存在【合同节点】和【金额】字段,显示小计
      if (
        type1list.includes('contractNodes') &&
        type1list.includes('Money')
      ) {
        haveAgreeTotal = true;
        AgreeColspan = 1;
        if (type1list.includes('NodeRatio')) {
          AgreeColspan += 1;
        }
        if (type1list.includes('paymentTerms')) {
          AgreeColspan += 1;
        }
      }
    }
    if (type2list.length > 0) {
      // 如果同时存在【成果提交日期】和【确认收入】字段,显示小计
      if (
        type2list.includes('submissionDate') &&
        type2list.includes('Income')
      ) {
        haveIncomeTotal = true;
        IncomeColspan = 1;
        if (type2list.includes('fileDate')) {
          IncomeColspan += 1;
        }
        if (type2list.includes('confirmationRatio')) {
          IncomeColspan += 1;
        }
      }
    }
    if (type3list.length > 0) {
      // 如果同时存在【到账日期】和【金额】字段,显示小计
      if (
        type3list.includes('DateofReceipt') &&
        type3list.includes('Money1')
      ) {
        haveReciveTotal = true;
        ReciveColspan = 1;
        if (type3list.includes('confirmationRatio1')) {
          ReciveColspan += 1;
        }
      }
    }

    // console.log('haveAgreeTotal, haveIncomeTotal, haveReciveTotal', haveAgreeTotal, haveIncomeTotal, haveReciveTotal)
    // console.log('AgreeColspan, IncomeColspan, ReciveColspan', AgreeColspan, IncomeColspan, ReciveColspan)
    return {
      haveAgreeTotal,
      haveIncomeTotal,
      haveReciveTotal,
      AgreeColspan,
      IncomeColspan,
      ReciveColspan,
    };
  };
  useEffect(() => {
    // setTableData(mockTableData)
    let source = formatData(mockTableData, rowData);
    setDataSource(source);
  }, []);
根据需求写入【小计】行
 const formatData = (data, rowData) => {
    
    let obj = handleColumnData(rowData);
    let resTableData = [];

    const {
      haveAgreeTotal,
      haveIncomeTotal,
      haveReciveTotal,
      AgreeColspan,
      IncomeColspan,
      ReciveColspan,
    } = obj;

    // 是否有任意一组列存在小计,存在则写入新一行
    // 循环列表,把数据分组写入
    // 写入小计行,根据列标识写入要合并的列数
    // 渲染时判断标识行,写入列数,其余为0
    if (haveAgreeTotal || haveIncomeTotal || haveReciveTotal) {
      Object.keys(data).forEach((key) => {
        let group = data[key];
        let nodeSum = 0;
          let IncomeSum = 0;
          let Money1Sum = 0;
        group.forEach((item) => {
          resTableData.push(item);
          nodeSum += item.NodeRatio;
          IncomeSum += item.Income;
         Money1Sum += item.Money1;
        });
        let totalRecord = {
          group: key,
          id: '',
          order: '',
          type: '',
          isConsortium: '',
          nameSquare: '',
          cstatus: '',
          money: '',
          value1: '',
          confirmIncome: '',
          receivables: '',
          agree: '',
          receivePayment: '',
        };
        if (haveAgreeTotal) {
          totalRecord.contractNodes = '小计';
          totalRecord.Money = nodeSum;
          totalRecord.NodeRatio = nodeSum;
          totalRecord.paymentTerms = nodeSum;
          totalRecord.AgreeColspan = AgreeColspan;
        }
        if (haveIncomeTotal) {
          totalRecord.submissionDate = '小计';
          totalRecord.Income = IncomeSum;
          totalRecord.fileDate = IncomeSum;
          totalRecord.confirmationRatio = IncomeSum;
          totalRecord.IncomeColspan = IncomeColspan;
        }
        if (haveReciveTotal) {
          totalRecord.DateofReceipt = '小计';
          totalRecord.Money1 = Money1Sum;
          totalRecord.confirmationRatio1 = Money1Sum;
          totalRecord.ReciveColspan = ReciveColspan;
        }
        // console.log('recordtotal', totalRecord)
        resTableData.push(totalRecord);
      });
    } else {
      Object.keys(data).forEach((key) => {
        let group = data[key];
        group.forEach((item) => {
          resTableData.push(item);
        });
      });
    }
return resTableData
  };
渲染表格

此处我们要注意的是!当前合并单元格行数、列数设置好后,我们要把【被合并的行列】都设置为0!!并且【其他的行和列】的合并数也要都为0!不然表格会出现错位问题!

我们把cloumns列设置

  {
          title: '合同约定',
          className: 'type1Column',
          children: [
            ...flattenData(rowData, 0)
              .filter((item) => item.checked)
              .filter((item) => item.type === 1)
              .map((item) => {
                return {
                  title: (
                    <div className="ellipsis-item" title={item.name}>
                      {item.name}
                    </div>
                  ),
                  dataIndex: item.key,
                  className: 'type1Column',
                  width: 100,
                  render: (text, record, index) => {
                    if (record.AgreeColspan) { // 判断是否是小计行
                      if (item.key === 'Money') {
                        return {
                          children: handleNode(item, text, 'total_back_pink'),
                          props: { colSpan: record.AgreeColspan }, // 合并"小计"行从第二列开始的所有列
                        };
                      } else if (item.key === 'contractNodes') {
                        return {
                          children: handleNode(item, text, 'total_back_pink'),
                          props: { colSpan: 1 }, // "小计"列不合并
                        };
                      } else {
                        return {
                          children: handleNode(item, text, 'total_back_pink'),
                          props: { colSpan: 0 }, // 当前组其他列设置为0,不会出现表格错位情况
                        };
                      }
                    } else {
                      return {
                        children: handleNode(item, text),
                        props: { colSpan: 1 }, // 非"小计"行全部不合并
                      };
                    }
                  },
                };
              }),
          ],
        },

这样就实现了【分组合并列】、【动态渲染列】啦!
在这里插入图片描述

2.合并行

思路

循环【数据源】,从第一行开始判断,如果【当前行】与【下一行】是同一组,那【rowSpan】 + 1,【被合并的行】记得要设置为0哦


  const formatData = (data, rowData) => {
 	 // 处理要合并的列
  	...

 	 // 处理要合并的行
    let processedData = [...resTableData];
    let prevFinishNum;
    let currentIndexForSameProperty;

    for (let i = 0; i < processedData.length; i++) {
      const currentItem = processedData[i];

      if (i === 0 || currentItem.group !== prevFinishNum) {
        // 新的组开始,重置计数器,并将上一组最后一项的rowSpan设置好
        if (
          prevFinishNum !== undefined &&
          currentIndexForSameProperty !== undefined
        ) {
          processedData[currentIndexForSameProperty].rowSpan =
            i - currentIndexForSameProperty;
        }
        currentIndexForSameProperty = i;
        currentItem.rowSpan = 1;
        currentItem.opcaty = '0'; // 标识是不是被合并的行
      } else {
        // 相同组内,累加rowSpan
        processedData[currentIndexForSameProperty].rowSpan += 1;
        currentItem.opcaty = '1'; // 标识是被合并的行
      }

      prevFinishNum = currentItem.group;
    }

    // 处理数组的最后一项
    if (
      currentIndexForSameProperty !== undefined &&
      currentIndexForSameProperty < processedData.length - 1
    ) {
      processedData[currentIndexForSameProperty].rowSpan =
        processedData.length - currentIndexForSameProperty;
    }

    return processedData;
 }

这样就实现了【合并行】啦!
在这里插入图片描述

3.嵌套表头

这个在 antd官网 都有,就是给columns设置children就行了,咱们在上面【渲染动态列】的代码里也有提到 ~
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2208921.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Milvus向量数据库管理工具[Attu]实践

Attu是一款专为Milvus向量数据库打造的开源数据库管理工具&#xff0c;提供了便捷的图形化界面&#xff0c;极大地简化了对Milvus数据库的操作与管理流程。阿里云Milvus集成了Attu&#xff0c;以便更加高效地管理数据库、集合&#xff08;Collection&#xff09;、索引&#xf…

protobufJavascrip编码解码演示

protobuf&Javascrip编码解码演示 start 写一下 protobuf 相关知识记录在 python 环境和 js 环境中如何处理 protobuf。 1. protobuf是什么&#xff1f; 1.1 介绍 Protocol Buffers(简称Protobuf) &#xff0c;是Google出品的序列化框架&#xff0c;与开发语言无关&…

【Go】GO语言知识总结浅析

Go语言是一种现代化的编程语言&#xff0c;由Google于2007年设计并于2009年发布。它旨在使编程变得简单、高效&#xff0c;并且可以在多核处理器上轻松构建高性能应用。Go语言的编程思想、发展历史、版本特点、运行原理、数据类型、应用场景&#xff0c;以及在web开发、网络编程…

C语言内存分配

概要 C语言的内存存储是一个复杂但非常重要的主题&#xff0c;涉及到静态内存、动态内存、指针、堆栈等多种机制&#xff0c;明白了c语言的内存分配&#xff0c;可以帮助我们更好的编程和学习c语言。 一.内存分配的类型 在C/C中内存分为5个区&#xff0c;分别为栈区、堆区、…

上海大爷惹恼韭菜不敢现身了

国庆节前股市暴涨&#xff0c;立即掀起了一股“全民炒股”热浪&#xff0c;但天不遂人愿&#xff0c;有大量韭菜散户很快就被套牢。 这与满嘴跑火车的上海大爷网红“爱在深秋”&#xff0c;曾鼓吹“A股会涨到上万点”多少有些关联。10月9日股市暴跌后&#xff0c;就不见他人影…

MySQL进阶 - SQL优化

01 插入数据 【一】insert优化&#xff1a; ① 不要一行一行插入数据&#xff0c;直接批量插入多行数据(但一个insert语句不要插入超过一千条)。 insert into 表名 (字段列表) values (xx,xx...),(xx,xx...)...&#xff1b; ② 在进行插入操作时手动提交事务&#xff0c;避免频…

【代码】集合set

哈喽大家好&#xff0c;我是学霸小羊&#xff0c;今天来讲一讲集合&#xff08;set&#xff09;。 在数学上&#xff0c;集合长这样&#xff1a; 那今天就来讲一讲编程上的集合。 集合的定义&#xff1a;把一些元素按照某些规律放在一起&#xff0c;就形成了一个集合。比如说…

PostgreSQL的学习心得和知识总结(一百五十四)|高级数据结构和算法之快速排序算法quicksort的实现及使用

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

鸿蒙UI系统组件16——富文本编辑器(RichEditor)

如果你也对鸿蒙开发感兴趣&#xff0c;加入“Harmony自习室”吧&#xff01;扫描下方名片&#xff0c;关注公众号&#xff0c;公众号更新更快&#xff0c;同时也有更多学习资料和技术讨论群。 RichEditor是支持图文混排和文本交互式编辑的组件&#xff0c;通常用于响应用户的对…

豆包MarsCode 合伙人计划限时招募中,推广最高赢万元现金!

豆包MarsCode 合伙人计划正式上线啦&#xff01;作为官方推出的推广激励项目&#xff0c;豆包MarsCode 编程助手号召和鼓励所有用户向我们推荐新用户。 现在正式开启首轮合伙人招募&#xff0c;诚邀各位有意愿推广普及 AI 编程产品的伙伴成为我们的合伙人&#xff0c;全国限量…

【Linux】操作系统基础

1.冯诺依曼体系结构介绍 冯诺依曼体系结构如下&#xff1a; 在上图中「输⼊设备」和「输出设备」⼀般被称为计算机的外设&#xff0c;⽽「存储器」在冯 诺依曼体系结构中表示「内存」 输⼊设备⼀般包括&#xff1a;⽹卡、磁盘、键盘、触摸屏等 输出设备⼀般包括&#xff1a;…

用 logfire 提高应用的可观测性

Logfire是由 Pydantic 团队打造的平台, 还有供 app 使用的 library, 我们经常提到对应用要做 LMT(Log, Metrics, Trace), Logfire 可以用来收集、存储、分析和可视化日志数据和应用性能指标。通过集成日志和度量&#xff0c;Logfire 提供了一个统一的界面来管理应用程序和系统的…

时间序列预测(一)——线性回归(linear regression)

目录 一、原理与目的 1、线性回归基于两个的假设&#xff1a; 2、线性回归的优缺点: 3、线性回归的主要目的是&#xff1a; 二、损失函数&#xff08;loss function&#xff09; 1、平方误差损失函数&#xff08;忽略了噪声误差&#xff09; 2、均方误差损失函数 三、随…

springboot项目通过maven的profile功能实现通过不同文件夹的方式来组织不同环境配置文件

写在前面 本文看下springboot项目如何通过文件夹的方式来组织不同环境配置文件。 1&#xff1a;正文 一般的我们写springboot项目时配置文件是这个样子的&#xff1a; appliction.yaml --> 通过spring.profiles.activexxx来激活某个指定后缀的配置文件 application-evn1…

【Java学习笔记】多线程

当我们在饭店聚餐时&#xff0c;多人同时吃一道菜的时候很容易发生争抢。例如&#xff0c;上了一道好菜&#xff0c;两个人同时夹这道菜&#xff0c;一人刚伸出筷子&#xff0c;结果伸到的时候菜已经被夹走了。为了避免这种现象&#xff0c;必须等一人 夹完一口后&#xff0c;另…

【大数据技术基础 | 实验一】配置SSH免密登录

文章目录 一、实验目的二、实验要求三、实验原理&#xff08;一&#xff09;大数据实验一体机&#xff08;二&#xff09;SSH免密认证 四、实验环境五、实验内容和步骤&#xff08;一&#xff09;搭建集群服务器&#xff08;二&#xff09;添加域名映射&#xff08;三&#xff…

工业物联网关-ModbusTCP

Modbus-TCP模式把网关视作Modbus从端设备&#xff0c;主端设备可以通过Modbus-TCP协议访问网关上所有终端设备。用户可以自定义多条通道&#xff0c;每条通道可以配置为TCP Server或者TCP Slave。注意&#xff0c;该模式需要指定采集通道&#xff0c;采集通道可以是串口和网口通…

51WORLD携手浙江科技大学,打造智慧校园新标杆

当前&#xff0c;国家教育数字化战略行动扎实推进&#xff0c;高等教育数字化转型步伐加快。 紧抓数字教育发展战略机遇&#xff0c;浙江科技大学联合51WORLD、正方软件股份有限公司&#xff08;简称&#xff1a;正方软件&#xff09;&#xff0c;共同研发打造浙科大孪生数智校…

为什么很多人宁愿加钱买港版,也不愿买国行 iPhone 16

最近的 iPhone 16 市场&#xff0c;真的是倒反天罡&#xff0c;攻守异形啊。 过去&#xff0c;港版 iPhone 都是性价比的次选&#xff0c;便宜个 10% 都得考虑考虑。但今年&#xff0c;港版 iPhone 16 的价格&#xff0c;反而比国行还贵。 比如&#xff0c;闲鱼上某个卖家&am…

Java消息摘要:MD5验证数据完整性、密码的加密与校验

MD5&#xff08;Message-Digest Algorithm 5&#xff09;是一种被广泛使用的密码散列函数&#xff0c;是一种不可逆的加密算法&#xff0c;该算法可以产生出一个128位&#xff08;16字节&#xff09;的散列值&#xff08;hash value&#xff09;&#xff0c;用于确保信息传输完…