Как лучше всего определить цифру слева от самого точного числа для чисел с нечетной и четной длиной? - PullRequest
0 голосов
/ 03 февраля 2019

Я пишу код, чтобы проверить, является ли определенное количество вводимых номеров кредитных карт действительным или нет.Я написал:

function validCreditCard(value) {
    // accept only digits, dashes or spaces
    if (value.trim().length <= 1) return 'Value entered must be greater than 1';
    if (/[^0-9\s]+/.test(value)) return false;

    // Remove all white spaces
    value = value.replace(/\D/g, '');

    for (var i = 0; i < value.length; i++) {
    // code goes here
    // Loop through the string from the rightmost moving left and double the value of every second digit.
}

Я пытался обернуть голову вокруг того, как Перебрать строку слева направо и удвоить значение каждой второй цифры , начиная с длиныстроки могут быть четными или нечетными.Например, для ввода с длиной 16 (четное) первое число слева будет 15-й позицией (индекс 14), а для ввода с нечетной длиной, такой как 11, первое число слева будет 10-й позицией (индекс 9).Я написал программу, которая не работала в обоих случаях, и теперь я хочу написать одну, чтобы удовлетворить оба.Как лучше всего добиться этого, не создавая две отдельные проверки, чтобы увидеть, является ли длина ввода нечетной или четной?

PS: Некоторые реализации в сети не работают и в обоих случаях.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Чтобы узнать, какие "каждая вторая цифра справа" , вам на самом деле не нужно итерировать с конца до начала.Это также можно сделать слева направо.Чтобы узнать, является ли цифра такой «второй» цифрой, сравните ее четность / нечетность с четностью длины входного сигнала.

Вот так:

var parity = value.length % 2;
for (var i = 0; i < value.length; i++) {
    if (i % 2 === parity) {
        // "Special" treatment comes here
    } else {
        // "Normal" treatment comes here
    }
}

Но выможет также просто добавить к входу ноль, если он имеет нечетную длину, чтобы придать ему четную длину:

if (value.length % 2) value = '0' + value;
for (var i = 0; i < value.length; i++) {
    if (i % 2 === 0) {
        // "Special" treatment comes here
    } else {
        // "Normal" treatment comes here
    }
}

То, что вы реализуете, называется алгоритм Луна .Так что с использованием четности длины это может выглядеть так:

function validCreditCard(value) {
    // Accept only digits, dashes or spaces
    if (/[^0-9\s-]+/.test(value)) return false;
    // Get the digits only
    value = value.replace(/\D/g, "");
    // Need at least one digit
    if (!value.length) return false;
    var parity = value.length % 2;
    var sum = 0;
    for (var i = 0; i < value.length; i++) {
        sum += i % 2 === parity
            ? (value[i]*2) % 10 + (value[i] > '4') // Double, and add one if double > 9
            : +value[i]; // Normal case
    }
    return sum%10 === 0;
}

console.log(validCreditCard("4024007112651582"));

Объяснение:

В цикле я заменил конструкцию if...else... условным троичным оператором - ... ? ... : ...- что является практичным, когда в обоих случаях вам нужно присвоить значение переменной (в нашем случае sum).

Для "обычных" цифр значение sum должно быть увеличено на значение цифры (+value[i]).Унарный оператор плюс преобразует символ в его числовое значение, поэтому +'1' становится 1.

Для «специальных» цифр значение sum должно быть увеличено вдвое по сравнению со значением цифры (value[i]*2),Обратите внимание, что здесь преобразование из строки в целое число происходит автоматически из-за умножения.

Тогда нам нужно разобраться со случаем, когда это двойное значение состоит из двух цифр.Например: 8 * 2 = 16. В этом случае результирующая цифра должна быть не 6, а 7. Поэтому мы добавляем (value[i] > '4').Это действительно логическое выражение (false или true): это правда, когда двойное имеет две цифры.Добавляя логическое значение, оно приводится к 0 или 1 соответственно - именно то, что нам нужно.

0 голосов
/ 03 февраля 2019

Зацикливать строку слева направо и удваивать значение каждой второй цифры

Вы можете использовать .reverse(), .map() и оператор остатка %

let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];

var res = [...arr].reverse().map((a, i) => i % 2 ? a * 2 : a).reverse();

console.log(res);
...