【问题标题】:Check for continuous order in array in javascript在javascript中检查数组中的连续顺序
【发布时间】:2013-04-27 07:12:31
【问题描述】:
var userInput = prompt('enter number here');
var number = new Array(userInput.toString().split(''));
if (number ????){ //checks if the number is in a continuous stream
alert(correct);
}
else{
alert(invalid);
}

在 Javascript 中,我可以在 "????" 处做什么检查它是否处于连续顺序/流中?另外,我该如何做到这一点,以便它仅在数组中的特定索引之后检查此订单/流?意思是用户输入说“12345678901234”会弹出正确,但“12347678901234”会弹出无效?(注意有两个7)对于第二部分“3312345678901234”会弹出正确,如何实现?

【问题讨论】:

  • 因为如果这有帮助的话 7 会破坏顺序
  • 假设不能跳过数字,但是当达到 0 时,订单必须重新开始
  • "3312345678901234" 将是有效的,因为如上所述,它只会在数组中的特定索引之后检查订单/流,在这种情况下,将设置为从索引 [2] 开始离开索引 [ 0],[1] 未选中

标签: javascript string stream continuous validating


【解决方案1】:

您可以创建一个函数来检查任何字符串是否存在从给定索引开始的连续/递增的字母数字字符流,如下所示:

function checkContinuous(str, startIndex) {
    startindex = startIndex || 0;
    if (str.length <= startIndex) {
        return false;
    }
    var last = str.charCodeAt(startIndex);
    for (var i = startIndex + 1; i < str.length; i++) {
        ++last;
        if (str.charCodeAt(i) !== last) {
            return false;
        }
    }
    return true;
}

如果它只是数字并且从 9 回绕到 0 被认为是连续的,那么它会像这样稍微复杂一点:

function checkContinuous(str, startIndex) {
    // make sure startIndex is set to zero if not passed in
    startIndex = startIndex || 0;
    // skip chars before startIndex
    str = str.substr(startIndex);
    // string must be at least 2 chars long and must be all numbers
    if (str.length < 2 || !/^\d+$/.test(str)) {
        return false;
    }
    // get first char code in string
    var last = str.charCodeAt(0);
    // for the rest of the string, compare to last code
    for (var i = 1; i < str.length; i++) {
        // increment last charCode so we can compare to sequence
        if (last === 57) {
            // if 9, wrap back to 0
            last = 48;
        } else {
           // else just increment
            ++last;
        }
        // if we find one char out of sequence, then it's not continuous so return false
        if (str.charCodeAt(i) !== last) {
            return false;
        }
    }
    // everything was continuous
    return true;
}

工作演示:http://jsfiddle.net/jfriend00/rHH4B/

【讨论】:

  • 打到0再开始会怎样?
  • @BigBob - 回零是否被认为是连续的?这仅适用于数字吗?连续的 alpha 序列呢?这会检查是否有任何字母数字序列不断增加。
  • 只是数字是的,我不太确定,但当它达到 0 时,它必须知道订单是重复的,因此仍然是连续的
  • @BigBob - 好的,我添加了第二个版本,它只用于数字并从 9 到 0 换行
  • 很抱歉,我在理解您的代码的工作原理时遇到了一点问题。看起来它正在工作,但是我不确定我是否能理解它并能够在我的代码中实现它像 (1,2,3,4,5,6)
【解决方案2】:

不需要数组,一次只返回一个字符。

当你击中 0 时,替换 10,然后继续直到数字 不比前一个多一个。

function continuousFromChar(str, start){
    start= start || 0;
    var i= 0, L= str.length, prev;
    while(L){
        c= +(str.charAt(-- L)) || 10; // use 10 for 0
        prev=+(str.charAt(L- 1));       
        if(c-prev  !== 1) break;
    }
    return  start>=L;
}

var s= "3312345678901234";

continuousFromChar(s,2)

/*  returned value: (Boolean)
true
*/

【讨论】:

    【解决方案3】:

    这将检查实时条目,但类似的原理可用于检查按钮提交或类似的条目。我不是 100% 确定你想要哪种方式,所以我选择了 live 方法。

    HTML

    <input id="stream" type="text" />
    

    Javascript

    window.addEventListener("load", function () {
        document.getElementById("stream").addEventListener("keyup", function (evt) {
            var target = evt.target;
            var value = target.value;
            var prev;
            var last;
            var expect;
    
            target.value = value.replace(/[^\d]/, "");
            if (value.length > 1) {
                prev = parseInt(value.slice(-2, -1), 10);
                last = parseInt(value.slice(-1), 10);
                expect = prev + 1;
    
                if (expect > 9) {
                    expect = 0;
                }
    
                if (last !== expect) {
                    target.value = value.slice(0, value.length - 1);
                }
            }
        }, false);
    });
    

    开启jsfiddle

    通过更改此处的值

    if (value.length > 1) {
    

    您可以更改检查的开始位置。

    更新:好的,这是您想要的函数,并且您坚持将字符串拆分为数组。然后使用上面的作为参考,你可以将它转换成这样的东西。

    Javascript

    window.addEventListener("load", function () {
        var testStrings = [
            "0123456789012",
            "0123456789",
            "0123455555",
            "555012345678901234",
            "0123455555"];
    
        function test(string, offset) {
            if (typeof string !== "string" || /[^\d]/.test(string)) {
                return false;
            }
    
            var array = string.split("");
            var prev;
            var last;
            var expect;
    
            return !array.some(function (digit, index) {
                if (index >= offset) {
                    prev = parseInt(array[index - 1], 10);
                    last = parseInt(digit, 10);
                    expect = prev + 1;
    
                    if (expect > 9) {
                        expect = 0;
                    }
    
                    if (last !== expect) {
                        return true;
                    }
                }
    
                return false;
            });
        }
    
        testStrings.forEach(function (string) {
            console.log(string, test(string, 1));
        });
    });
    

    开启jsfiddle

    由于您的问题并未完全说明所有可能性,因此上述内容将为空字符串 ("") 返回 true,当然您可以简单地在开头添加一个检查。

    我也不会为您的偏移量执行任何有效数字检查,但这也是您可以添加的简单内容。

    当然,这些只是众多可能的解决方案中的一(两个),但希望它能让您的思想朝着正确的方向发展。

    【讨论】:

    • 这比我要求的要多得多,但是您的 if 语句几乎就是我想要的,但是您能告诉我如何通过从数组中提取值来执行您的 if 语句哪个从我的原始帖子中获取它的值?(所以用户输入然后它被检查)
    【解决方案4】:

    这里有一些很好的答案,但我想展示一些细微的变化。我认为展示 JavaScript 的一些不同方面以及区分代码中的兴趣很重要。

    1. 函数作为第一类对象很酷 - 只需更改谓词函数即可更改“连续”的确切规则。也许我们应该允许跳过数字?没问题。也许我们允许十六进制数字?没问题。只需针对特定规则更改相应的follows 函数即可。

    2. 这可以通用实现,因为字符串支持索引。这将与具有适当follows 函数的其他类似数组的对象一样工作。请注意,continuous 函数中没有使用特定于字符串的函数。

    代码also on jsfiddle:

    // returns true only iff b "follows" a; this can be changed
    function follows_1Through9WithWrappingTo0(b,a) {
        if (b === "1" && a === undefined) {
            // start of sequence
            return true;
        } else if (b === "0" && a === "9") {
            // wrap
            return true;
        } else {
            // or whatever
            return (+b) === (+a) + 1;
        }
    }
    
    function continuous(seq, accordingTo, from) {
       // strings can be treated like arrays; this code really doesn't care
       // and could work with arbitrary array-like objects
       var i = from || 0;
       if ((seq.length - i) < 1) {
           return true;
       }
       var a = undefined;
       var b = undefined;
       for (; i < seq.length; i++) {
          b = seq[i];
          if (!accordingTo(b, a)) {
             return false; // not continuous
          }
          a = b;
       }
       return true;
    }
    
    function assert(label, expr, value) {
        if (!(expr === value)) {
            alert("FAILED: " + label);
        }
    }
    
    var follows = follows_1Through9WithWrappingTo0;
    assert("empty1", continuous("", follows), true);
    assert("empty2", continuous("foobar", follows, 6), true);
    assert("skip", continuous("331234", follows, 2), true);
    assert("good 1", continuous("123456789", follows), true);
    assert("good 2", continuous("12345678901234", follows), true);
    assert("bad seq 1", continuous("12347678901234", follows), false);
    assert("bad seq 2", continuous("10", follows), false);
    
    // here a different predicate ensures all the elements are the same
    var areAllSame = function (b, a) {
                         return a === undefined || a === b;
                     };
    assert("same", continuous("aaaaa", areAllSame), true);
    

    请注意,也可以从 continuous 函数中提取跳过:在具有更好“功能”集合支持的语言中,例如 C#,这正是我要做的首先 .

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-05
      • 2020-09-13
      • 2016-01-16
      • 1970-01-01
      • 2021-12-09
      • 2022-11-10
      • 1970-01-01
      相关资源
      最近更新 更多