根据用户选择的行和列数据构造数据结构(跨行跨列)
方案一
这段代码的功能是根据用户选择的行和列数据,生成一个适合复制粘贴的字符串表格。代码会先按列的 id 从小到大排序,再根据行列的选择关系将数据按顺序填入表格,每行之间使用换行符分隔,每列之间使用制表符分隔。如果某一行缺少对应列的数据,则在该位置插入空格。
注意事项
- 列排序:代码先根据
id对所选列数据进行排序,确保生成的表格中列顺序一致。 - 行列对应关系:每列数据包含一个
_X_ROW_KEY属性,表示它对应的行。代码会检查列和行的_X_ROW_KEY是否匹配,只有匹配的列才会填入数据,否则填入空位。 - 空位占位:如果某行在某列没有数据,为了保持列对齐,会插入空字符串。
代码字段解释
selectedRows:用户选择的行数据,每行数据代表一个完整的数据对象,其中包含了字段id、name、sex等字段,并用_X_ROW_KEY标记它属于哪一行。selectedColumns:用户选择的列数据,每列包含field(对应行的字段)、title(列标题)、id(列的唯一标识)等属性。_X_ROW_KEY数组标记该列在哪些行中有数据。sortedColumns:排序后的列数组,确保列输出时按id的升序排列。
代码实现
// 所选行数据
const selectedRows = [{ "id": 1, "name": "张三", "age": 30, "sex": "男", "job": "前端", "address": "中国xxxxxxxxxx", "_X_ROW_KEY": "row_8" },{ "id": 2, "name": "李四", "age": 30, "sex": "男", "job": "后端", "address": "中国xxxxxxxxxx", "_X_ROW_KEY": "row_10" }
];// 所选列数据
const selectedColumns = [{ "property": "name", "field": "name", "title": "姓名", "width": 100, "fixed": "left", "align": "left", "filterMultiple": true, "id": "col_09", "_X_ROW_KEY": ["row_8"] },{ "property": "job", "field": "job", "title": "职务", "width": 100, "fixed": "left", "align": "left", "filterMultiple": true, "id": "col_34", "_X_ROW_KEY": ["row_10"] },{ "property": "address", "field": "address", "title": "地址", "width": 100, "fixed": "left", "align": "left", "filterMultiple": true, "id": "col_35", "_X_ROW_KEY": ["row_10","row_8"] },{ "property": "sex", "field": "sex", "title": "性别", "width": 100, "fixed": "left", "align": "left", "filterMultiple": true, "id": "col_10", "_X_ROW_KEY": ["row_8","row_10"] }
];// 组装数据结构并生成拼接字符串
function assembleSelectedDataString(selectedRows, selectedColumns) {// 对 selectedColumns 按列的 id 从小到大排序,确保输出中列的顺序一致const sortedColumns = selectedColumns.sort((a, b) => parseInt(a.id.replace("col_", "")) - parseInt(b.id.replace("col_", "")));// 初始化一个空数组,用来存储每一行的拼接数据const rows = [];// 遍历行数据,对每一行处理一次selectedRows.forEach(row => {const rowKey = row._X_ROW_KEY; // 获取当前行的唯一标识符,用来匹配列数据const rowData = []; // 存储当前行对应的每列数据// 遍历排序后的列数据,保证列顺序输出正确sortedColumns.forEach(column => {// 检查当前列是否包含该行数据的 _X_ROW_KEYif (column._X_ROW_KEY.includes(rowKey)) {// 如果列的 _X_ROW_KEY 包含当前行的 rowKey,则插入对应的字段值rowData.push(row[column.field]);} else {// 如果不包含,则插入空字符串,占位使列对齐rowData.push("");}});// 将当前行数据(用制表符连接每列数据)添加到 rows 数组中rows.push(rowData.join("\t"));});// 将所有行数据连接成一个字符串,每行之间用换行符分隔return rows.join("\n");
}// 调用函数获取拼接后的字符串
const selectedDataString = assembleSelectedDataString(selectedRows, selectedColumns);
console.log(selectedDataString);
示例输出
张三 男 中国xxxxxxxxxx男 后端 中国xxxxxxxxxx
方案二
这段代码的目的是根据输入的行数据和列数据生成一个格式化的字符串,字符串中的列使用制表符 (\t) 分隔,行使用换行符 (\n) 分隔,方便输出和阅读。每一列的数据会根据最大列宽对齐,以确保输出的格式整齐。
const data = [{ "rowIndex": 2, "columnIndex": 5, "value": "2218123959094757194" },{ "rowIndex": 2, "columnIndex": 6, "value": "2-6" },{ "rowIndex": 3, "columnIndex": 5, "value": "2218123959094757194" },{ "rowIndex": 3, "columnIndex": 6, "value": "3-6" },{ "rowIndex": 4, "columnIndex": 5, "value": "2218123959094757194" },{ "rowIndex": 4, "columnIndex": 6, "value": "4-6" },{ "rowIndex": 5, "columnIndex": 5, "value": "2218123959094757194" },{ "rowIndex": 5, "columnIndex": 6, "value": "5-6" },{ "rowIndex": 6, "columnIndex": 5, "value": "2218123959094757194" },{ "rowIndex": 7, "columnIndex": 7, "value": "7-7-7-7-7-7" },{ "rowIndex": 7, "columnIndex": 8, "value": "7-8-7-8-7-8" },
];// 定义一个函数,用于生成格式化的表格字符串
function generateCompactTableString(data) {// 计算表格的最大行索引const maxRow = Math.max(...data.map(item => item.rowIndex));// 提取所有列索引并去重、排序,得到一个有序的列索引数组const columnIndices = Array.from(new Set(data.map(item => item.columnIndex))).sort((a, b) => a - b);// 创建一个二维数组,用于存储每个单元格的内容// 行数为 maxRow + 1,列数为 columnIndices 的长度,初始化为空字符串const table = Array.from({ length: maxRow + 1 }, () => Array(columnIndices.length).fill(""));// 遍历输入数据,将值填入对应的表格位置data.forEach(item => {const { rowIndex, columnIndex, value } = item; // 解构出行索引、列索引和值const colIndex = columnIndices.indexOf(columnIndex); // 找到列索引在表格中的位置if (colIndex !== -1) { // 如果该列索引存在table[rowIndex][colIndex] = value; // 将值填入表格}});// 计算每列的最大宽度,以便后续对齐const columnWidths = columnIndices.map((_, colIndex) => Math.max(...table.map(row => row[colIndex].length)) // 计算每列的最大字符长度);// 过滤掉空行const nonEmptyRows = table.filter(row => row.some(cell => cell !== "")); // 只保留至少有一个非空单元格的行// 将表格内容转换为字符串,用制表符分隔列return nonEmptyRows.map(row => row.map((cell, colIndex) => cell.padEnd(columnWidths[colIndex]) // 确保每列宽度一致,使用空格填充).join("\t") // 用制表符连接列).join("\n"); // 用换行符连接行
}// 输出格式化后的表格字符串
const compactTableString = generateCompactTableString(data);
console.log(compactTableString); // 打印输出结果
各字段解释
-
data:一个包含多个对象的数组。每个对象代表一个单元格的数据,包含以下字段:rowIndex:表示数据所在的行索引(从0开始计数)。columnIndex:表示数据所在的列索引(从0开始计数)。value:该单元格要显示的内容。
-
generateCompactTableString(data):一个函数,用于生成格式化的表格字符串。- 参数:
data,上面定义的数组。 - 返回值:格式化后的表格字符串,列用制表符分隔,行用换行符分隔。
- 参数:
-
maxRow:通过遍历data数组,找出最大的rowIndex值,以确定表格的行数。 -
columnIndices:使用Set来提取并去重所有的columnIndex,然后将其排序,得到一个有序的列索引数组。 -
table:一个二维数组,用于存储每个单元格的内容。它的行数为maxRow + 1,列数为columnIndices的长度,初始时填充为空字符串。 -
padEnd:用于确保每列的宽度一致,通过在每个单元格内容后面填充空格。
相关文章:
根据用户选择的行和列数据构造数据结构(跨行跨列)
方案一 这段代码的功能是根据用户选择的行和列数据,生成一个适合复制粘贴的字符串表格。代码会先按列的 id 从小到大排序,再根据行列的选择关系将数据按顺序填入表格,每行之间使用换行符分隔,每列之间使用制表符分隔。如果某一行…...
Spark教程5-基本结构化操作
加载csv文件 df spark.read.format("json").load("/data/flight-data/json/2015-summary.json")Schema 输出Schema df.printSchema()使用Schema读取csv文件,以指定数据类型 from pyspark.sql.types import StructField, StructType, Strin…...
内置数据类型、变量名、字符串、数字及其运算、数字的处理、类型转换
内置数据类型 python中的内置数据类型包括:整数、浮点数、布尔类型(以大写字母开头)、字符串 变量名 命名变量要见名知意,确保变量名称具有描述性和意义,这样可以使得代码更容易维护,使用_可以使得变量名…...
Win/Mac/Android/iOS怎麼刪除代理設置?
設置代理設置的主要構成 IP 地址和端口 這些是代理伺服器配置的最基本組件。代理伺服器的IP地址引導互聯網流量,而端口號指定伺服器上的通信通道。 為什麼要刪除代理設置? 刪除代理設置通常是為了解決網路問題、提高速度、恢復安全性或過渡到新的網路…...
数据结构------手撕顺序表
文章目录 线性表顺序表的使用及其内部方法ArrayList 的扩容机制顺序表的几种遍历方式顺序表的优缺点顺序表的模拟实现洗牌算法 线性表 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,…...
UDP(用户数据报协议)端口监控
随着网络的扩展,确保高效的设备通信对于优化网络功能变得越来越重要。在这个过程中,端口发挥着重要作用,它是实现外部设备集成的物理连接器。通过实现数据的无缝传输和交互,端口为网络基础设施的顺畅运行提供了保障。端口使数据通…...
【Java小白图文教程】-05-数组和排序算法详解
精品专题: 01.《C语言从不挂科到高绩点》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. 《SpringBoot详细教程》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12789841.html?spm1001.20…...
OpenCV视觉分析之目标跟踪(1)计算密集光流的类DISOpticalFlow的介绍
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 这个类实现了 Dense Inverse Search (DIS) 光流算法。更多关于该算法的细节可以在文献 146中找到。该实现包含了三个预设参数集,以提…...
Lucas带你手撕机器学习——套索回归
好的,下面我将详细介绍套索回归的背景、理论基础、实现细节以及在实践中的应用,同时还会讨论其优缺点和一些常见问题。 套索回归(Lasso Regression) 1. 背景与动机 在机器学习和统计学中,模型的复杂性通常会影响其在…...
面试中的一个基本问题:如何在数据库中存储密码?
面试中的一个基本问题:如何在数据库中存储密码? 在安全面试中,“如何在数据库中存储密码?”是一个基础问题,但反映了应聘者对安全最佳实践的理解。以下是安全存储密码的最佳实践概述。 了解风险 存储密码必须安全&am…...
XML HTTP Request
XML HTTP Request 简介 XMLHttpRequest(XHR)是一个JavaScript对象,它最初由微软设计,并在IE5中引入,用于在后台与服务器交换数据。它允许网页在不重新加载整个页面的情况下更新部分内容,这使得网页能够实现动态更新,大大提高了用户体验。虽然名字中包含“XML”,但XML…...
TLS协议基本原理与Wireshark分析
01背 景 随着车联网的迅猛发展,汽车已经不再是传统的机械交通工具,而是智能化、互联化的移动终端。然而,随之而来的是对车辆通信安全的日益严峻的威胁。在车联网生态系统中,车辆通过无线网络与其他车辆、基础设施以及云端服务进行…...
当遇到 502 错误(Bad Gateway)怎么办
很多安装雷池社区版的时候,配置完成,访问的时候可能会遇到当前问题,如何解决呢? 客户端,浏览器排查 1.刷新页面和清除缓存 首先尝试刷新页面,因为有时候 502 错误可能是由于网络临时波动导致服务器无法连…...
学习记录:js算法(七十五): 加油站
文章目录 加油站思路一思路二思路三思路四思路五 加油站 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发…...
强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断
强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断 目录 强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断效果一览基本介绍程序设计参考资料 效果一览 基本介绍 EEMD-MPE-KPCA-LSTM(集合经验模态分解-多尺…...
yarn的安装与使用以及与npm的区别(安装过程中可能会遇到的问题)
一、yarn的安装 使用npm就可以进行安装 但是需要注意的一点是yarn的使用和node版本是有关系的必须是16.0以上的版本。 输入以下代码就可以实现yarn的安装 npm install -g yarn 再通过版本号的检查来确定,yarn是否安装成功 yarn -v二、遇到的问题 1、问题描述…...
大数据行业预测
大数据行业预测 编译 李升伟 和所有预测一样,我们必须谨慎对待这些预测,因为其中一些预测可能成不了事实。当然,真正改变游戏规则的创新往往出乎意料,甚至让最警惕的预言家也措手不及。所以,如果在来年发生了一些惊天…...
可能是NextJs(使用ssr、api route)打包成桌面端(nextron、electron、tauri)的最佳解决方式
可能是NextJs(使用ssr、api route)打包成桌面端(nextron、electron、tauri)的最佳解决方式 前言 在我使用nextron(nextelectron)写了一个项目后打包发现nextron等一系列桌面端框架在生产环境是不支持next的ssr也就是api route功能的这就导致我非常难受&…...
二百七十、Kettle——ClickHouse中增量导入清洗数据错误表
一、目的 比如原始数据100条,清洗后,90条正确数据在DWD层清洗表,10条错误数据在DWD层清洗数据错误表,所以清洗数据错误表任务一定要放在清洗表任务之后。 更关键的是,Hive中原本的SQL语句,放在ClickHouse…...
CentOS6升级OpenSSH9.2和OpenSSL3
文章目录 1.说明2.下载地址3.升级OpenSSL4.安装telnet 服务4.1.安装 telnet 服务4.2 关闭防火墙4.2.使用 telnet 连接 5.升级OpenSSH5.1.安装相关命令依赖5.2.备份原 ssh 配置5.3.卸载原有的 OpenSSH5.4.安装 OpenSSH5.5.修改 ssh 配置文件5.6关闭 selinux5.7.重启 OpenSSH 1.说…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
