【vue2+js】记录如何校验一组数据中是否有区间重叠

embedded/2024/12/21 12:01:11/

界面样子
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
html代码片段

javascript"><template><div class="threshold-wrap"><el-form class="threshold-list" ref="form"><span v-for="(v, vIndex) in thresholdList" :key="v.id"><el-form-item prop="symbol" class="symbol" v-if="v.symbol !== 'to'"><el-select v-model="v.symbol" size="mini" placeholder=""><el-optionv-for="s in symbolList":key="s.id":label="s.label":value="s.id"></el-option></el-select></el-form-item><el-form-item:prop="v.symbol !== 'to' ? 'indexValueList' : ''"class="indexValueList"><template v-if="v.symbol === 'to'"><template v-if="v.dataType === 1"><el-select v-model="v.contain1" size="mini" placeholder=""><el-optionv-for="s in toList":key="s.id":label="s.label":value="s.id"></el-option></el-select><el-date-pickerv-model="v.containVal1"type="date"size="mini":clearable="false"placeholder=""format="yyyy-MM-dd"value-format="timestamp"></el-date-picker>~<el-select v-model="v.contain2" size="mini" placeholder=""><el-optionv-for="s in toList":key="s.id":label="s.label":value="s.id"></el-option></el-select><el-date-pickerv-model="v.containVal2"type="date"size="mini":clearable="false"placeholder=""format="yyyy-MM-dd"value-format="timestamp"></el-date-picker></template><template v-else-if="v.dataType === 2"><el-select v-model="v.contain1" size="mini" placeholder=""><el-optionv-for="s in toList":key="s.id":label="s.label":value="s.id"></el-option></el-select><el-inputv-model="v.containVal1"size="mini"placeholder=""type="number"@input="handleInput($event, vIndex, 'containVal1')"></el-input>~<el-select v-model="v.contain2" size="mini" placeholder=""><el-optionv-for="s in toList":key="s.id":label="s.label":value="s.id"></el-option></el-select><el-inputv-model="v.containVal2"size="mini"placeholder=""type="number"@input="handleInput($event, vIndex, 'containVal2')"></el-input></template></template><template v-else><template v-if="v.dataType === 1"><el-date-pickerv-model="v.indexValueList"type="date"size="mini":clearable="false"placeholder=""format="yyyy-MM-dd"value-format="timestamp"></el-date-picker></template><template v-else-if="v.dataType === 2"><el-inputv-model="v.indexValueList"size="mini"placeholder=""type="number"@input="handleInput($event, vIndex)"></el-input></template></template></el-form-item><el-form-item prop="score" class="score"><el-input-numberv-model="v.score"size="mini"type="number":min="0":max="100"></el-input-number></el-form-item><el-form-item><i class="el-icon-delete" @click="del(vIndex)"></i></el-form-item></span><el-button icon="el-icon-plus" size="mini" @click="add">添加</el-button></el-form><div class="footer"><el-buttontype="primary"size="mini"@click="handleSave">保存</el-button></div></div>
</template>

js代码片段

javascript"><script>
export default {name: 'Threshold',components: {},props: {},data() {return {thresholdList: [],symbolList: [{id: 'gt',label: '>',},{id: 'lt',label: '<',},{id: 'equ',label: '=',},{id: 'ne',label: '≠',},{id: 'gte',label: '≥',},{id: 'le',label: '≤',},{id: 'to',label: '~',},],toList: [{id: 'contain',label: '含',},{id: 'notContain',label: '不含',}],toListMap: [{id: 'gt_lt',label: ['notContain', 'notContain'],},{id: 'gt_le',label: ['notContain', 'contain'],},{id: 'gte_lt',label: ['contain', 'notContain'],},{id: 'gte_le',label: ['contain', 'contain'],},],}},watch: {},computed: {},created() {},mounted() {},methods: {add() {this.thresholdList = this.thresholdList.concat({dataType: 2,symbol: null,indexValueList: null,score: null,contain1: null,contain2: null,containVal1: null,containVal2: null,})},del(vIndex) {this.thresholdList = this.thresholdList.filter((element, eIndex) => vIndex !== eIndex);},isOnlyWhitespace(str) {  return /^\s*$/.test(str)},isBlank(val) {if(typeof val === 'number') {return false}else if(typeof val === 'boolean') {return false}else if(typeof val === 'string' && this.isOnlyWhitespace(val)){return true}else {return _.isEmpty(val)}},handleInput(value, vIndex, type) {this.thresholdList = this.thresholdList.map((item, index) => {if(index === vIndex) {if(item.symbol !== 'to') {return {...item, indexValueList: value.startsWith('.') ? '0' + value : value,}}else {if(type === 'containVal1') {return {...item, containVal1: value.startsWith('.') ? '0' + value : value,}}else if(type === 'containVal2') {return {...item, containVal2: value.startsWith('.') ? '0' + value : value,}}}}return item})},// 将关系符转换为区间toInterval(obj) {let start, endconst epsilon = 1e-9    // 1e-9表示浮点数,具体是0.000000001,一个很小的可以忽略不计的数// symbol='to'时,indexValueList是数组,存两个数字,否则就是string,一个数字const value = obj.symbol !== 'to' && parseFloat(obj.indexValueList)switch(obj.symbol) {case 'gt':// >start = value + epsilonend = Infinitybreakcase 'lt':// <start = -Infinityend = value - epsilonbreakcase 'gte':// ≥start = valueend = Infinitybreakcase 'le':// ≤start = -Infinityend = valuebreakcase 'equ':// =return { point: value }case 'gt_lt':// (a, b)start = parseFloat(obj.indexValueList[0]) + epsilonend = parseFloat(obj.indexValueList[1]) - epsilonbreakcase 'gt_le':// (a, b]start = parseFloat(obj.indexValueList[0]) + epsilonend = parseFloat(obj.indexValueList[1])breakcase 'gte_lt':// [a, b)start = parseFloat(obj.indexValueList[0])end = parseFloat(obj.indexValueList[1]) - epsilonbreakcase 'gte_le':// [a, b]start = parseFloat(obj.indexValueList[0])end = parseFloat(obj.indexValueList[1])break// case 'ne'://   // ≠//   return { neqValue: value }}return { start, end }},// 校验是否重叠checkOverlap(a, b) {// 第一种情况:两条数据一个是区间,一个是=具体数据if((a.point !== undefined && b.start !== undefined && b.end !== undefined) || (b.point !== undefined && a.start !== undefined && a.end !== undefined)) {// 分两种情况:1、第一条数据是=,第二条数据是区间;2、第一条数据是区间,第二条数据是=if(a.point !== undefined && b.start !== undefined && b.end !== undefined) {return !(a.point < b.start || a.point>b.end)}if(a.start !== undefined && a.end !== undefined && b.point !== undefined) {return !(b.point < a.start || b.point > a.end)}return false    // 区间和=的没有重叠}else if(a.start !== undefined && a.end !== undefined && b.start !== undefined && b.end !== undefined) {// 第二种情况:两条数据都是区间return !(a.start > b.end || a.end < b.start)}else if(a.point !== undefined && b.point !== undefined) {// 第三种情况:两条数据都是=return a.point === b.point}},/*** * @param int1 第一条数据* @param int2 第二条数据*/check(int1, int2, i, j) {if(int1.point !== undefined && int2.start !== undefined && int2.end !== undefined) {if(this.checkOverlap({point: int1.point}, {start: int2.start, end: int2.end})) {return `${i+1}行(= ${int1.point})落在第${j+1}行的区间内\n`}}if(int1.start !== undefined && int1.end !== undefined && int2.point !== undefined) {if(this.checkOverlap({start: int1.start, end: int1.end}, {point: int2.point})) {return `${j+1}行(= ${int2.point})落在第${i+1}行的区间内\n`}}if(int1.start !== undefined && int1.end !== undefined && int2.start !== undefined && int2.end !== undefined) {if(this.checkOverlap({start: int1.start, end: int1.end}, {start: int2.start, end: int2.end})) {return `${i+1}行和第${j+1}行有重叠\n`}}if(int1.point !== undefined && int2.point !== undefined) {if(int1.point === int2.point) {return `${i+1}行(= ${int1.point})和第${j+1}行(= ${int2.point})有重复\n`}}return false},// 校验阈值,首先不能为空,其次:一行算一条数据,每个数据之间不能有重叠区间handleSave() {if(!this.thresholdList.length) {this.$message.error('请添加阈值')return}if(this.thresholdList && this.thresholdList.length>0) {const newlist = this.thresholdList.map(item => {if(item.symbol === 'to') {const foundTo = this.toListMap.find(v => JSON.stringify(v.label) === JSON.stringify([item.contain1, item.contain2]))const symbol = foundTo && foundTo.idreturn {symbol,indexValueList: [item.containVal1, item.containVal2],score: item.score,}} return item})// 1、判空let info1 = []newlist.forEach((item, index) => {if(this.isBlank(item.symbol) || this.isBlank(item.indexValueList) || this.isBlank(item.score)) {info1.push(`${index+1}行数据不完整\n`)}      })// 2、校验阈值重叠,thresholdList中不止两条数据,两两比较所有的数据const n = newlist.lengthlet info2 = []for (let i = 0; i < n; i++) {const int1 = this.toInterval(newlist[i])   //将数据转换为区间for (let j = i + 1; j < n; j++) {const int2 = this.toInterval(newlist[j])// 如果重叠,将提示信息塞进info2数组中this.check(int1, int2, i, j) && info2.push(this.check(int1, int2, i, j))}}if(info1 && info1.length>0) {this.$message({message: info1.join(''),type: 'error',customClass: 'custom-message',})}else if(info2 && info2.length>0) {this.$message({message: info2.join(''),type: 'error',customClass: 'custom-message',})}else {this.$message.success('保存成功')}}}},
}
</script>

style样式片段

javascript"><style lang="scss" scoped>
.threshold-wrap {width: 100%;height: 100%;display: flex;flex-direction: column;.threshold-list {width: 100%;flex: 1;&>span {display: flex;.indexValueList {::v-deep .el-form-item__content {display: flex;}}.el-icon-delete {cursor: pointer;margin-left: 10px;color: #409eff;}}}
}// 隐藏数字输入框的选择器
::v-deep input[type="number"]::-webkit-outer-spin-button,
::v-deep input[type="number"]::-webkit-inner-spin-button {-webkit-appearance: none;margin: 0;
}::v-deep input[type="number"] {-moz-appearance: textfield;
}
</style><style lang="scss">
.custom-message {white-space: pre-line; /* 使 \n 生效 */.el-message__content {line-height: 20px;}
}
</style>

完整代码

javascript"><template><div class="threshold-wrap"><el-form class="threshold-list" ref="form"><span v-for="(v, vIndex) in thresholdList" :key="v.id"><el-form-item prop="symbol" class="symbol" v-if="v.symbol !== 'to'"><el-select v-model="v.symbol" size="mini" placeholder=""><el-optionv-for="s in symbolList":key="s.id":label="s.label":value="s.id"></el-option></el-select></el-form-item><el-form-item:prop="v.symbol !== 'to' ? 'indexValueList' : ''"class="indexValueList"><template v-if="v.symbol === 'to'"><template v-if="v.dataType === 1"><el-select v-model="v.contain1" size="mini" placeholder=""><el-optionv-for="s in toList":key="s.id":label="s.label":value="s.id"></el-option></el-select><el-date-pickerv-model="v.containVal1"type="date"size="mini":clearable="false"placeholder=""format="yyyy-MM-dd"value-format="timestamp"></el-date-picker>~<el-select v-model="v.contain2" size="mini" placeholder=""><el-optionv-for="s in toList":key="s.id":label="s.label":value="s.id"></el-option></el-select><el-date-pickerv-model="v.containVal2"type="date"size="mini":clearable="false"placeholder=""format="yyyy-MM-dd"value-format="timestamp"></el-date-picker></template><template v-else-if="v.dataType === 2"><el-select v-model="v.contain1" size="mini" placeholder=""><el-optionv-for="s in toList":key="s.id":label="s.label":value="s.id"></el-option></el-select><el-inputv-model="v.containVal1"size="mini"placeholder=""type="number"@input="handleInput($event, vIndex, 'containVal1')"></el-input>~<el-select v-model="v.contain2" size="mini" placeholder=""><el-optionv-for="s in toList":key="s.id":label="s.label":value="s.id"></el-option></el-select><el-inputv-model="v.containVal2"size="mini"placeholder=""type="number"@input="handleInput($event, vIndex, 'containVal2')"></el-input></template></template><template v-else><template v-if="v.dataType === 1"><el-date-pickerv-model="v.indexValueList"type="date"size="mini":clearable="false"placeholder=""format="yyyy-MM-dd"value-format="timestamp"></el-date-picker></template><template v-else-if="v.dataType === 2"><el-inputv-model="v.indexValueList"size="mini"placeholder=""type="number"@input="handleInput($event, vIndex)"></el-input></template></template></el-form-item><el-form-item prop="score" class="score"><el-input-numberv-model="v.score"size="mini"type="number":min="0":max="100"></el-input-number></el-form-item><el-form-item><i class="el-icon-delete" @click="del(vIndex)"></i></el-form-item></span><el-button icon="el-icon-plus" size="mini" @click="add">添加</el-button></el-form><div class="footer"><el-buttontype="primary"size="mini"@click="handleSave">保存</el-button></div></div>
</template><script>
export default {name: 'Threshold',components: {},props: {},data() {return {thresholdList: [],symbolList: [{id: 'gt',label: '>',},{id: 'lt',label: '<',},{id: 'equ',label: '=',},{id: 'ne',label: '≠',},{id: 'gte',label: '≥',},{id: 'le',label: '≤',},{id: 'to',label: '~',},],toList: [{id: 'contain',label: '含',},{id: 'notContain',label: '不含',}],toListMap: [{id: 'gt_lt',label: ['notContain', 'notContain'],},{id: 'gt_le',label: ['notContain', 'contain'],},{id: 'gte_lt',label: ['contain', 'notContain'],},{id: 'gte_le',label: ['contain', 'contain'],},],}},watch: {},computed: {},created() {},mounted() {},methods: {add() {this.thresholdList = this.thresholdList.concat({dataType: 2,symbol: null,indexValueList: null,score: null,contain1: null,contain2: null,containVal1: null,containVal2: null,})},del(vIndex) {this.thresholdList = this.thresholdList.filter((element, eIndex) => vIndex !== eIndex);},isOnlyWhitespace(str) {  return /^\s*$/.test(str)},isBlank(val) {if(typeof val === 'number') {return false}else if(typeof val === 'boolean') {return false}else if(typeof val === 'string' && this.isOnlyWhitespace(val)){return true}else {return _.isEmpty(val)}},handleInput(value, vIndex, type) {this.thresholdList = this.thresholdList.map((item, index) => {if(index === vIndex) {if(item.symbol !== 'to') {return {...item, indexValueList: value.startsWith('.') ? '0' + value : value,}}else {if(type === 'containVal1') {return {...item, containVal1: value.startsWith('.') ? '0' + value : value,}}else if(type === 'containVal2') {return {...item, containVal2: value.startsWith('.') ? '0' + value : value,}}}}return item})},// 将关系符转换为区间toInterval(obj) {let start, endconst epsilon = 1e-9    // 1e-9表示浮点数,具体是0.000000001,一个很小的可以忽略不计的数// symbol='to'时,indexValueList是数组,存两个数字,否则就是string,一个数字const value = obj.symbol !== 'to' && parseFloat(obj.indexValueList)switch(obj.symbol) {case 'gt':// >start = value + epsilonend = Infinitybreakcase 'lt':// <start = -Infinityend = value - epsilonbreakcase 'gte':// ≥start = valueend = Infinitybreakcase 'le':// ≤start = -Infinityend = valuebreakcase 'equ':// =return { point: value }case 'gt_lt':// (a, b)start = parseFloat(obj.indexValueList[0]) + epsilonend = parseFloat(obj.indexValueList[1]) - epsilonbreakcase 'gt_le':// (a, b]start = parseFloat(obj.indexValueList[0]) + epsilonend = parseFloat(obj.indexValueList[1])breakcase 'gte_lt':// [a, b)start = parseFloat(obj.indexValueList[0])end = parseFloat(obj.indexValueList[1]) - epsilonbreakcase 'gte_le':// [a, b]start = parseFloat(obj.indexValueList[0])end = parseFloat(obj.indexValueList[1])break// case 'ne'://   // ≠//   return { neqValue: value }}return { start, end }},// 校验是否重叠checkOverlap(a, b) {// 第一种情况:两条数据一个是区间,一个是=具体数据if((a.point !== undefined && b.start !== undefined && b.end !== undefined) || (b.point !== undefined && a.start !== undefined && a.end !== undefined)) {// 分两种情况:1、第一条数据是=,第二条数据是区间;2、第一条数据是区间,第二条数据是=if(a.point !== undefined && b.start !== undefined && b.end !== undefined) {return !(a.point < b.start || a.point>b.end)}if(a.start !== undefined && a.end !== undefined && b.point !== undefined) {return !(b.point < a.start || b.point > a.end)}return false    // 区间和=的没有重叠}else if(a.start !== undefined && a.end !== undefined && b.start !== undefined && b.end !== undefined) {// 第二种情况:两条数据都是区间return !(a.start > b.end || a.end < b.start)}else if(a.point !== undefined && b.point !== undefined) {// 第三种情况:两条数据都是=return a.point === b.point}},/*** * @param int1 第一条数据* @param int2 第二条数据*/check(int1, int2, i, j) {if(int1.point !== undefined && int2.start !== undefined && int2.end !== undefined) {if(this.checkOverlap({point: int1.point}, {start: int2.start, end: int2.end})) {return `${i+1}行(= ${int1.point})落在第${j+1}行的区间内\n`}}if(int1.start !== undefined && int1.end !== undefined && int2.point !== undefined) {if(this.checkOverlap({start: int1.start, end: int1.end}, {point: int2.point})) {return `${j+1}行(= ${int2.point})落在第${i+1}行的区间内\n`}}if(int1.start !== undefined && int1.end !== undefined && int2.start !== undefined && int2.end !== undefined) {if(this.checkOverlap({start: int1.start, end: int1.end}, {start: int2.start, end: int2.end})) {return `${i+1}行和第${j+1}行有重叠\n`}}if(int1.point !== undefined && int2.point !== undefined) {if(int1.point === int2.point) {return `${i+1}行(= ${int1.point})和第${j+1}行(= ${int2.point})有重复\n`}}return false},// 校验阈值,首先不能为空,其次:一行算一条数据,每个数据之间不能有重叠区间handleSave() {if(!this.thresholdList.length) {this.$message.error('请添加阈值')return}if(this.thresholdList && this.thresholdList.length>0) {const newlist = this.thresholdList.map(item => {if(item.symbol === 'to') {const foundTo = this.toListMap.find(v => JSON.stringify(v.label) === JSON.stringify([item.contain1, item.contain2]))const symbol = foundTo && foundTo.idreturn {symbol,indexValueList: [item.containVal1, item.containVal2],score: item.score,}} return item})// 1、判空let info1 = []newlist.forEach((item, index) => {if(this.isBlank(item.symbol) || this.isBlank(item.indexValueList) || this.isBlank(item.score)) {info1.push(`${index+1}行数据不完整\n`)}      })// 2、校验阈值重叠,thresholdList中不止两条数据,两两比较所有的数据const n = newlist.lengthlet info2 = []for (let i = 0; i < n; i++) {const int1 = this.toInterval(newlist[i])   //将数据转换为区间for (let j = i + 1; j < n; j++) {const int2 = this.toInterval(newlist[j])// 如果重叠,将提示信息塞进info2数组中this.check(int1, int2, i, j) && info2.push(this.check(int1, int2, i, j))}}if(info1 && info1.length>0) {this.$message({message: info1.join(''),type: 'error',customClass: 'custom-message',})}else if(info2 && info2.length>0) {this.$message({message: info2.join(''),type: 'error',customClass: 'custom-message',})}else {this.$message.success('保存成功')}}}},
}
</script><style lang="scss" scoped>
.threshold-wrap {width: 100%;height: 100%;display: flex;flex-direction: column;.threshold-list {width: 100%;flex: 1;&>span {display: flex;.indexValueList {::v-deep .el-form-item__content {display: flex;}}.el-icon-delete {cursor: pointer;margin-left: 10px;color: #409eff;}}}
}// 隐藏数字输入框的选择器
::v-deep input[type="number"]::-webkit-outer-spin-button,
::v-deep input[type="number"]::-webkit-inner-spin-button {-webkit-appearance: none;margin: 0;
}::v-deep input[type="number"] {-moz-appearance: textfield;
}
</style><style lang="scss">
.custom-message {white-space: pre-line; /* 使 \n 生效 */.el-message__content {line-height: 20px;}
}
</style>

http://www.ppmy.cn/embedded/147523.html

相关文章

【设计模式】空接口

&#xff08;空&#xff09;接口的用法总结 接口用于定义某个类的特定能力或特性。在工作流或任务管理系统中&#xff0c;接口可以帮助标识哪些任务可以在特定阶段执行。通过实现这些接口&#xff0c;任务类可以被标识为在相应的阶段可以执行&#xff0c;从而在验证和执行逻辑…

vue create 创建项目 提示 Failed to check for updates 淘宝 NPM 镜像站喊你切换新域名啦

1、使用 vue create demo创建项目的时候发现 提示 “Failed to check for updates”&#xff0c; 执行 npm config list 看了一下 镜像源是&#xff1a;https://registry.npm.taobao.org 然后搜索一下发现这个淘宝这个镜像域名切换了。 公告地址&#xff1a;【公告】淘宝 npm …

WebMvcConfigurer和WebMvcConfigurationSupport(MVC配置)

一:基本介绍 WebMvcConfigurer是接口&#xff0c;用于配置全局的SpringMVC的相关属性&#xff0c;采用JAVABean的方式来代替传统的XML配置文件&#xff0c;提供了跨域设置、静态资源处理器、类型转化器、自定义拦截器、页面跳转等能力。 WebMvcConfigurationSupport是webmvc的…

【C语言】打牌游戏

相信你是最棒哒&#xff01;&#xff01;&#xff01; 文章目录 题目描述 正确代码 总结 题目描述 Suneet 和 Slavic 玩一个卡牌游戏。游戏规则如下&#xff1a; 每张卡片的整数值在 1 和 10之间。每位玩家获得 2 张面朝下的卡片&#xff08;因此玩家不知道自己的卡片&#…

《剑网三》遇到找不到d3dx9_42.dll的问题要怎么解决?缺失d3dx9_42.dll是什么原因?

《剑网三》游戏运行中d3dx9_42.dll缺失问题深度解析与解决方案 在畅游《剑网三》的武侠世界时&#xff0c;不少玩家可能会遇到系统提示“找不到d3dx9_42.dll”的报错信息。这一突如其来的问题不仅让游戏进程受阻&#xff0c;还可能让玩家陷入困惑与无奈。我将为大家深入剖析这…

Qt Quick:CheckBox 复选框

复选框不止选中和未选中2种状态哦&#xff0c;它还有1种部分选中的状态。这3种状态都是Qt自带的&#xff0c;如果想让复选框有部分选中这个状态&#xff0c;需要将三态属性&#xff08;tristate&#xff09;设为true。 未选中的状态值为0&#xff0c;部分选中是1&#xff0c;选…

实战技巧 DevEco Profiler 性能调优 Time

实战技巧 DevEco Profiler 性能调优 Time 背景 DevEco Studio 开发工具中提供了 Profiler 面板&#xff0c;可以让我们在针对实际开发应用过程中碰到的一些性能相关的问题提供解决方案。如响应速度慢、动画卡顿、内存泄漏、发热、耗电快等等场景。其中 Profiler 提供了实时监…

iOS在项目中设置 Dev、Staging 和 Prod 三个不同的环境

在 Objective-C 项目中设置 Dev、Staging 和 Prod 三个不同的环境&#xff0c;并为每个环境使用不同的 Bundle ID&#xff0c;可以通过以下步骤实现&#xff1a; 步骤 1: 创建不同的 Build Configuration 打开项目&#xff1a; 启动 Xcode 并打开你的项目。 选择项目文件&…