间隔验证
Interval Validation
本文关键字:验证 更新时间:2023-09-26
我们有三个不同的网页,其中包含网格,用于添加主实体的详细信息。
Detail对象可以通过用javascript表示
var detail = {
Description: 'Detail',
MinPercentage: 0,
MaxPercentage: 20
}
现在,我们希望在发送到服务器之前验证这些详细信息。
验证
- 不得有任何交叉点。即细节(‘细节1’,0,20)和细节(‘详情2’,15,30)无效,因为15和20之间是共同的
- 细节包含从给定最小值到给定最大值的值。即细节(‘细节1’,0,20)和细节(‘详情2’,20,40)保持0到40的值。如果给定的最小值为0,给定的最大值为40,则它们是有效的
职能部门的期望
- 因为我想编写一个在多个地方使用的函数,所以应该尽可能通用
然后,我编写了一个名为areIntervalsValid的函数,但我不知道如何处理输入错误的调用、抛出异常、返回最佳结构化结果,我还想知道执行验证的最佳方式是什么。
// Returns array of detail object to test.
var getDetails = function () {
var detail1 = { Description: 'Detail1', MinPercentage: 0, MaxPercentage: 20 }
var detail2 = { Description: 'Detail2', MinPercentage: 40, MaxPercentage: 60 }
var detail3 = { Description: 'Detail3', MinPercentage: 60, MaxPercentage: 72 }
var detail4 = { Description: 'Detail4', MinPercentage: 72, MaxPercentage: 100 }
var detail5 = { Description: 'Detail5', MinPercentage: 20, MaxPercentage: 40 }
return new Array(detail1, detail2, detail3, detail4, detail5);
}
// Performs type checking, logical validation, and requirements validation.
var areIntervalsValid = function (items, min, max, minProperty, maxProperty) {
// Returned object.
var result = {
Success: false,
Message: ''
}
// Checks arguments have expected types.
var validateFunctionCall = function () {
if (!Array.isArray(items) || typeof min !== 'number' || typeof max !== 'number' || typeof minProperty !== 'string' || typeof maxProperty !== 'string')
throw 'An error occurred while processing validation.';
if (!items.length || min > max)
throw 'An error occurred while processing validation.';
}
// Checks [minProperty] of detail that has minimum [minProperty] == min
// and [maxProperty] of detail that has maximum [minProperty]
var validateIntervalBasics = function () {
if (items[0][minProperty] != min || items[items.length - 1][maxProperty] != max)
throw 'Start and end values of interval do not match minimum - maximum values.';
}
// Checks @item has [minProperty] and [maxProperty].
var validateHasProperty = function (item) {
if (!item.hasOwnProperty(minProperty) || !item.hasOwnProperty(maxProperty)) {
throw 'An error occurred while processing validation.';
}
}
try {
validateFunctionCall();
// Sorts array of details in according to [minProperty].
items.sort(function (item1, item2) { return item1[minProperty] > item2[minProperty] });
validateIntervalBasics();
var totalDiff = 0, currentItem;
// Algorithm part.
for (var i = 0; i < items.length; i++) {
currentItem = items[i];
validateHasProperty(currentItem);
totalDiff += currentItem[maxProperty] - currentItem[minProperty];
if (i != items.length - 1 && currentItem[maxProperty] > items[i + 1][minProperty]) { // Finds intersections.
throw "There are intersected values: " + currentItem[maxProperty] + " - " + items[i + 1][minProperty];
}
}
// Checks second validation.
if (totalDiff != max - min) {
throw 'Total interval sum is not equal to ' + (max - min);
}
result.Success = true;
return result;
} catch (e) {
console.log(e);
result.Message = e;
return result;
}
}
然后,我调用这样的函数:
areIntervalsValid(getDetails(), 0, 100, "MinPercentage", "MaxPercentage");
我可以对函数做些什么,使其更加可靠、通用和快速?
如果您使用函数式编程原理,尤其是递归,可以用更好的方式实现这一点。
这是我解决这个问题的办法。没有数据类型验证逻辑,因为我相信你可以自己做:
// Numbers and intervals comparison logic
function intervalsIntersect(start1, end1, start2, end2) {
return inBetween(start1, start2, end2) || inBetween(end1, start2, end2);
}
function inBetween(value, start, end){
return Math.max.apply(null, arguments) != value && Math.min.apply(null, arguments) != value;
}
// Validation logic
function getDetailsIntersectionReport(interval1, interval2) {
var comparisonResult = intervalsIntersect(interval1.MinPercentage, interval1.MaxPercentage, interval2.MinPercentage, interval2.MaxPercentage);
return comparisonResult ? ('[' + interval1.Description + ' instersects with ' + interval2.Description + '], ') : '';
}
function compareHeadWithTailFunctionFactory(head, comparatorFunction) {
return function ( previous, item) {
return previous + comparatorFunction(head, item);
}
}
// you have to inject custom comparator function to make this function generic
function validateWithReport(list, comparatorFunction) {
if (list.length <= 1) { // return if there is nothing to compare
return '';
}
var head = list[0];
var tail = list.slice(1);
return tail.reduce(compareHeadWithTailFunctionFactory(head, comparatorFunction),
'' // initial value - empty string
) + validateWithReport(tail, comparatorFunction);
}
function validateIntervals(intervals) {
var result = validateWithReport(intervals, getDetailsIntersectionReport);
if (result.length) {
throw new Error('There are intersecting intervals: ' + result);
}
return true;
}
// Unit test with Jasmine
describe('validation with report', function() {
var intervalsWithoutIntersections = [
{ Description: 'Detail1', MinPercentage: 0, MaxPercentage: 20 },
{ Description: 'Detail2', MinPercentage: 40, MaxPercentage: 60 },
{ Description: 'Detail3', MinPercentage: 60, MaxPercentage: 72 }
];
var intervalsWithIntersections = [
{ Description: 'Detail4', MinPercentage: 0, MaxPercentage: 21 },
{ Description: 'Detail5', MinPercentage: 20, MaxPercentage: 60 },
{ Description: 'Detail6', MinPercentage: 60, MaxPercentage: 72 }
];
it('should report with exception about error', function() {
expect( function() { // wrapping into closure to catch error properly
validateIntervals(intervalsWithIntersections)
}).toThrowError();
});
it('should report validation with true', function() {
expect(validateIntervals(intervalsWithoutIntersections)).toBeTruthy();
});
});
相关文章:
- 正在验证8个真/假复选框或复选框中的2个
- 借助asp.net验证或java脚本对多个文本进行验证
- jQuery自定义验证比较多个输入的序列
- 使用html中的外部javascript进行数据验证
- 如何使用jquery Validation验证Formspread
- jquery中的文本框验证
- 在验证和发送邮件后更改联系人表单的 html
- 代码不会验证
- JS验证ajax返回的html中的表单数据
- 同步调用,直到用户通过angular验证为访问者
- 带有加号的电话号码验证(可选)
- 解析javascript表单验证器
- 两位数的月份日期验证
- 使用angularjs验证文本框中的电子邮件
- 验证Javascript中的Textarea
- 使用regex的jquery keydown绑定不会验证撇号和句点
- Jquery表单验证插件-如果选中复选框,如何在提交时执行某些操作
- 正在删除node.js中已验证的网站
- 自定义表单验证和提交
- 带有验证和隐藏字段值的提交按钮