为什么它只返回 false?Luhn 算法

huangapple go评论57阅读模式
英文:

why it is returning only false? Luhn algorithm

问题

以下是您要翻译的代码部分:

//arrays :
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];

const validateCred = Array => {
    let cardNum = 0
    let reverseArray = Array.reverse()
    for (let i = 0; i < reverseArray.length; i++){

        let newVar = reverseArray[i]

        if (i%2 !== 0){
            newVar = reverseArray[i] * 2
            if (newVar > 9){
                newVar = newVar[i] - 9;
                cardNum += newVar
            } else {
                cardNum += newVar
            }
        } else {
            cardNum += reverseArray[i]
        }
    }
    return(cardNum%10 === 0 ? true : false)
}
console.log(validateCred(valid1))

如果您需要进一步的解释或帮助,请告诉我。

英文:

What's wrong with my code? It should return true for this array. The invalid one should return false.
Please explain it to me because i'm just started with JS

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

//arrays :
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];

const validateCred = Array =&gt; {
    let cardNum = 0
    let reverseArray = Array.reverse()
    for (let i = 0; i &lt; reverseArray.length; i++){

        let newVar = reverseArray[i]

       if (i%2 !== 0){
        newVar = reverseArray[i] * 2
            if (newVar &gt; 9){
                newVar = newVar[i] - 9;
                cardNum += newVar
            } else {
                cardNum += newVar
            }
       } else {
        cardNum += reverseArray[i]
       }
    }
    return(cardNum%10 === 0 ? true : false)
}
console.log(validateCred(valid1))

<!-- end snippet -->

答案1

得分: 1

正如您在评论中指出并指出的那样 `newVar` 是一个数字时这将不会顺利进行

```js
newVar = newVar[i] - 9;

正如 Pointy 所指出的那样,“Array” 是一个糟糕的变量名,会遮蔽一个重要的构造函数。更甚的是,在 JavaScript 中有一个强烈的约定:以大写字母开头的变量名是为构造函数保留的。 我建议使用描述变量用途而非类型的名称。也许 &quot;creditCard&quot; 是个不错的选择,或者根据您对缩写的接受程度,可以选择 &quot;cc&quot;

但这段代码还存在另一个更微妙的问题。它改变了输入:

const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
console .log (validateCred (valid1)) //=&gt; true
console .log (valid1) //=&gt; [8, 0, 8, 6, 1, 0, 8, 0, 9, 7, 7, 6, 9, 3, 5, 4]

在真实应用中,这可能会导致各种问题,也许在这段代码附近的地方,总是很令人沮丧。

修复起来很容易。只需在颠倒之前克隆数组。有很多方法可以做到这一点(例如使用 myVariable.slice()myVariable.concat())。我现在更倾向于使用扩展运算符将其展开到一个新数组中:[...myVariable]


在我回答另一个 Luhn 算法问题的 答案 中,我发展了我认为是一种优雅版本的该算法。如果您是 JavaScript 新手,可能会使用到一些您不熟悉的功能,但我认为它清晰而有用。这是稍微改进的版本:

const luhn = (ds) =&gt; (
  [...ds]
    .filter(d =&gt; /^\d$/ .test (d))
    .reverse () 
    .map (Number) 
    .map ((d, i) =&gt; i % 2 == 1 ? (2 * d &gt; 9 ? 2 * d - 9 : 2 * d) : d) 
    .reduce ((a, b) =&gt; a + b, 0) 
) % 10 == 0

这是相同的算法,只是表达得更为简洁。在初始值的展开和 filter 调用之间(删除非数字字符),它允许我们传递各种输入格式:

const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = &quot;4539677908016808&quot;
const valid3 = &quot;4539-6779-0801-6808&quot;
const valid4 = &quot;4539 6779 0801 6808&quot;

<details>
<summary>英文:</summary>

As you figured out and noted in the comments, this is not going to go well when `newVar` is a number:

```js
newVar = newVar[i] - 9;

And as Pointy, um, pointed out, Array is a terrible name for a variable, shadowing an important constructor function. More than that, there is a strong convention in JS that InitialCapital variable names are reserved for constructor functions. I would suggest a name that describes what it's for, not its type. Perhaps &quot;creditCard&quot; would be useful, or, depending on your tolerance for short abbreviations, &quot;cc&quot;.

But there's another, more subtle, problem with this code. It alters its input:

const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
console .log (validateCred (valid1)) //=&gt; true
console .log (valid1) //=&gt; [8, 0, 8, 6, 1, 0, 8, 0, 9, 7, 7, 6, 9, 3, 5, 4]

In a real application, this could cause you all sorts of problems, and maybe far away from this section, always frustrating.

It's easy enough to fix. Just clone the array before reversing it. There are many ways to do it (using myVariable.slice() or myVariable.concat(), for instance.) My preference these days is to spread it into a new array: [...myVariable].


In my answer to another Luhn's Algorithm question, I developed what I think of as an elegant version of this algorithm. If you're new to JS, this may use some features you're not familiar with, but I find it clear and useful. This is a slightly improved version:

const luhn = (ds) =&gt; (
  [...ds]
    .filter(d =&gt; /^\d$/ .test (d))
    .reverse () 
    .map (Number) 
    .map ((d, i) =&gt; i % 2 == 1 ? (2 * d &gt; 9 ? 2 * d - 9 : 2 * d) : d) 
    .reduce ((a, b) =&gt; a + b, 0) 
) % 10 == 0

It's the same algorithm, just expressed a little more concisely. Between the spreading of the initial value and the filter call (removing non-digits), it allows us to pass various input formats:

const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = &quot;4539677908016808&quot;
const valid3 = &quot;4539-6779-0801-6808&quot;
const valid4 = &quot;4539 6779 0801 6808&quot;

huangapple
  • 本文由 发表于 2023年2月7日 02:59:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75365497.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定