创建字母和数字的范围

Create range of letters and numbers

本文关键字:范围 数字 创建      更新时间:2023-09-26

我正在创建一个表单,用户可以在其中输入范围。他们可以输入字母和数字。一些示例输入:

From: AA01
To:   AZ02

结果应该是:

AA01
AA02
AB01
AB02
And so on, till AZ02

:

From: BC01
To:   DE01

应该导致:

BC01
BD01
BE01
CC01
CD01
CE01
Etc

我设法让它为输入A01到D10工作(例如)

jsFiddle

但是,我不能让它工作与多个字母。

JS代码:

var $from = $('input[name="from"]');
var $to = $('input[name="to"]');
var $quantity = $('input[name="quantity"]');
var $rangeList = $('.rangeList');
var $leadingzeros = $('input[name="leadingzeros"]');
$from.on('keyup blur', function () {
    $(this).val($(this).val().replace(/[^a-zA-Z0-9]/g, ''));
    updateQuantity();
});
$to.on('keyup blur', function () {
    $(this).val($(this).val().replace(/[^a-zA-Z0-9]/g, ''));
    updateQuantity();
});
$leadingzeros.on('click', function () {
    updateQuantity();
});
function updateQuantity() {
    var x = parseInt($from.val().match(/'d+/));
    var y = parseInt($to.val().match(/'d+/));
    var xl = $from.val().match(/[a-zA-Z]+/);
    var yl = $to.val().match(/[a-zA-Z]+/);
    var result = new Array();
    if (xl != null && yl != null && xl[0].length > 0 && yl[0].length > 0) {
        xl = xl[0].toUpperCase();
        yl = yl[0].toUpperCase();
        $rangeList.html('');
        var a = yl.charCodeAt(0) - xl.charCodeAt(0);
        for (var i = 0; i <= a; i++) {
            if (!isNaN(x) && !isNaN(y)) {
                if (x <= y) {
                    var z = (y - x) + 1;
                    $quantity.val(z * (a + 1));
                    $rangeList.html('');
                    for (var b = z; b > 0; b--) {
                        var c = ((y - b) + 1);
                        if ($leadingzeros.prop('checked')) {
                            c = leadingZeroes(c, y.toString().length);
                        }
                        result.push(String.fromCharCode(65 + i) + c);
                    }
                } else {
                    $rangeList.html('');
                    $quantity.val(0);
                }
            } else {
                $rangeList.html('');
                $quantity.val(0);
            }
        }
    } else if (!isNaN(x) && !isNaN(y)) {
        if (x < y) {
            var z = (y - x) + 1;
            $quantity.val(z);
            $rangeList.html('');
            for (var i = z; i > 0; i--) {
                var c = (y - i) + 1;
                if ($leadingzeros.prop('checked')) {
                    c = leadingZeroes(c, y.toString().length);
                }
                result.push(c);
            }
        } else {
            $rangeList.html('');
            $quantity.val(0);
        }
    } else {
        $rangeList.html('');
        $quantity.val(0);
    }
    $rangeList.html('');
    for (var i = 0; i < result.length; i++) {
        $rangeList.append(result[i] + '<br />');
    }
}
function leadingZeroes(number, size) {
    number = number.toString();
    while (number.length < size) number = "0" + number;
    return number;
}

这对于递归算法来说是完美的:

function createRange(from, to) {
    if (from.length === 0) {
        return [ "" ];
    }
    var result = [];
    var innerRange = createRange(from.substring(1), to.substring(1));
    for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
        for (var j = 0; j < innerRange.length; j++) {
            result.push(String.fromCharCode(i) + innerRange[j]);
        }
    }
    return result;
}

调用如下:

createRange('BC01', 'DE02'); // Generates an array containing all values expected

EDIT:修改了下面的函数,以匹配新的测试用例(但是更加混乱,涉及到字符串和整数之间的大量类型强制转换)。

function prefixZeroes(value, digits) {
    var result = '';
    value = value.toString();
    for (var i = 0; i < digits - value.length; i++) {
        result += '0';
    }
    return result + value;
}
function createRange(from, to) {
    if (from.length === 0) {
        return [ "" ];
    }
    var result = [];
    if (from.charCodeAt(0) < 65) {
        fromInt = parseInt(from);
        toInt   = parseInt(to);
        length  = toInt.toString().length;
        var innerRange = createRange(from.substring(length), to.substring(length));
        for (var i = fromInt; i <= toInt; i++) {
            for (var j = 0; j < innerRange.length; j++) {
                result.push(prefixZeroes(i, length) + innerRange[j]);
            }
        }
    } else {
        var innerRange = createRange(from.substring(1), to.substring(1));
        for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
            for (var j = 0; j < innerRange.length; j++) {
                result.push(String.fromCharCode(i) + innerRange[j]);
            }
        }
    }
    return result;
}

请注意,因为你严格的逻辑在如何增加这个方法需要正好4个字符(2个字母后面跟着2个数字)的工作。此外,这可能不像它可以的那样高效/整洁,但它需要一些修补才能满足您的逻辑需求。

function generate(start, end) {
    var results = [];
    //break out the start/end letters/numbers so that we can increment them seperately
    var startLetters = start[0] + start[1];
    var endLetters = end[0] + end[1];
    var startNumber = Number(start[2] + start[3]);
    var endNumber = Number(end[2] + end[3]);
    //store the start letter/number so we no which value to reset the counter to when a maximum boundry in reached
    var resetLetter = startLetters[1];
    var resetNumber = startNumber;
    //add first result as we will always have at least one
    results.push(startLetters + (startNumber < 10 ? "0" + startNumber : "" + startNumber));
    //maximum while loops for saefty, increase if needed
    var whileSafety = 10000;
    while (true) {
        //safety check to ensure while loop doesn't go infinite
        whileSafety--;
        if (whileSafety == 0) break;
        //check if we have reached the maximum value, if so stop the loop (break)
        if (startNumber == endNumber && startLetters == endLetters) break;
        //check if we have reached the maximum number. If so, and the letters limit is not reached
        //then reset the number and increment the letters by 1
        if (startNumber == endNumber && startLetters != endLetters) {
            //reset the number counter
            startNumber = resetNumber;
            //if the second letter is at the limit then reset it and increment the first letter, 
            //otherwise increment the second letter and continue
            if (startLetters[1] == endLetters[1]) {
                startLetters = '' + String.fromCharCode(startLetters.charCodeAt(0) + 1) + resetLetter;
            } else {
                startLetters = startLetters[0] + String.fromCharCode(startLetters.charCodeAt(1) + 1);
            }
        } else {
            //number limit not reached so just increment the number counter
            startNumber++;
        }
        //add the next sequential value to the array
        results.push(startLetters + (startNumber < 10 ? "0" + startNumber : "" + startNumber));
    }
    return results;
}
var results = generate("BC01", "DE01");
console.log(results);
下面是一个工作示例,它使用了第二个测试用例

使用@Phylogenesis'代码,我成功地实现了我的目标。

<<p> jsFiddle演示/strong>
function updateQuantity() {
    var x = parseInt($from.val().match(/'d+/));
    var y = parseInt($to.val().match(/'d+/));
    var xl = $from.val().match(/[a-zA-Z]+/);
    var yl = $to.val().match(/[a-zA-Z]+/);
    var result = new Array();
    var r = createRange(xl[0], yl[0]);
    var z = (y - x) + 1;
    if (x <= y) {
        for (var j = 0; j < r.length; j++) {
            var letters = r[j];
            for (var i = z; i > 0; i--) {
                var c = (y - i) + 1;
                if ($leadingzeros.prop('checked')) {
                    c = leadingZeroes(c, y.toString().length);
                }
                if (i == z) {
                    r[j] = letters + c + '<br />';
                } else {
                    j++;
                    r.splice(j, 0, letters + c + '<br />');
                }
            }
        }
    } else {
        for (var i = 0; i < r.length; i++) {
            r[i] += '<br />';
        }
    }
    $quantity.val(r.length);
    $rangeList.html('');
    for (var i = 0; i < r.length; i++) {
        $rangeList.append(r[i]);
    }
}

这适用于无限的字母和数字,只要字母在前面。

谢谢你的帮助!