创建字母和数字范围

时间:2014-03-20 14:39:29

标签: javascript jquery html

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

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;
}

3 个答案:

答案 0 :(得分:4)

这非常适合递归算法:

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

编辑:修改后的函数以匹配新的测试用例(更麻烦,但是,涉及字符串和整数之间的大量类型强制)。

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;
}

答案 1 :(得分:1)

请注意,由于您对值增加的严格逻辑,此方法需要正好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);

Here is a working example,它使用您的第二个测试用例

答案 2 :(得分:-1)

使用 @Phylogenesis &#39;代码,我设法实现了我的目标。

<强> jsFiddle demo

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]);
    }
}

只要字母是第一个,这适用于无限的字母和数字。

感谢您的帮助!