chenhuiYj / note

开发笔记
6 stars 0 forks source link

练习题5:模拟实现开闭区间 #16

Open chenhuiYj opened 4 years ago

chenhuiYj commented 4 years ago

判断一个数字,是否在若干个区间范围之中,区分开区间和闭区间。 比如

  1. checkRanges(2,'[1,2]') 输出为 true 。因为 2 在区间 [1,2] 中,checkRanges(2,'[1,2)') 输出为 false,因为2不在区间 [1,2) 中

2.区间数量无限制 checkRanges(2,'[2,5],(6,10)....')

function checkRanges(num,ranges){
    function handle(num,str){
        let _num=+str.replace(/\D/g,'')
        if(/\[\d+/.test(str)){
            return num>=_num
        }
        else if(/\(\d+/.test(str)){
            return num>_num
        }
        else if(/\d+\]/.test(str)){
            return num<=_num
        }
        else if(/\d+\)/.test(str)){
            return num<_num
        }
    }
    let _ranges=ranges.match(/\D\d+\,\d+\D/g)
    let nowRange=[]
    return _ranges.some(item=>{
        nowRange=item.split(',')
        return  handle(num,nowRange[0])&&handle(num,nowRange[1])
    })
}

checkRanges(2,'[1,2]')//true
checkRanges(2,'[1,2)')//false
checkRanges(5,'[1,2),[3,6]')//true

在实际开发上,很多时候是需要考虑负数和小数的,实现起来也不难,只是把正则改一下而已

function checkRanges(num,ranges){
    function handle(num,str){
        let _num=+str.replace(/[\[\]\(\)]/g,'')
        if(/\[(\-?(Infinity|0|([1-9]\d*))(\.\d+)?)/.test(str)){
            return num>=_num
        }
        else if(/\((\-?(Infinity|0|([1-9]\d*))(\.\d+)?)/.test(str)){
            return num>_num
        }
        else if(/(\-?(Infinity|0|([1-9]\d*))(\.\d+)?)\]/.test(str)){
            return num<=_num
        }
        else if(/(\-?(Infinity|0|([1-9]\d*))(\.\d+)?)\)/.test(str)){
            return num<_num
        }
    }
    let _ranges=ranges.match(/\D(\-?(Infinity|0|([1-9]\d*))(\.\d+)?)\,(\-?(Infinity|0|([1-9]\d*))(\.\d+)?)\D/g)
    let nowRange=[]
    return _ranges.some(item=>{
        nowRange=item.split(',')
        return  handle(num,nowRange[0])&&handle(num,nowRange[1])
    })
}

checkRanges(2.5,'[2.5,5]')//true
checkRanges(2.5,'(2.5,5]')//false
checkRanges(-2.5,'(-3,5]')//true
checkRanges(-2.5,'(-2.5,5]')//false
checkRanges(-2.5,'(-2.6,5]')//true
checkRanges(Infinity,'[2.5,Infinity]')//true

然后看到正则写了N次,代码太长,也可以优化

function checkRanges(num,ranges){
    function handle(num,range,type){
        switch(type){
            case '[':return num>=range;
            case '(':return num>range;
            case ']':return num<=range;
            case ')':return num<range;
        }
    }
    let _ranges=ranges.split(/[\]\)],[\[\(]/g)
    let nowRange=[]
    return _ranges.some(item=>{
        nowRange=item.match(/[\(\)\[\]]|(\-?(Infinity|0|([1-9]\d*))(\.\d+)?)/g)
        return  handle(num,+nowRange[1],nowRange[0])&&handle(num,nowRange[2],nowRange[3])
    })
}

checkRanges(2.5,'[2,2.1],[2.5,3]')//true
checkRanges(2.5,'[2,2.1],(2.5,3]')//false