检查 JavaScript 数组中数字序列的最有效方法是什么?

Luk*_*uke 5 javascript algorithm

背景

在一次技术面试中,我的任务是用 JavaScript 实现一个缺失的算法。面试官向我提供了一些代码和 18 个失败的单元测试,一旦算法成功实现,这些单元测试就会通过。我确信有一种更有效的方法来解决这个问题,因为我在规定的时间内尝试了几种不同的方法。这是我开始工作的第一种方法,对于技术测试来说已经足够了,但我想知道解决问题的更好方法。

问题

计算出扑克牌中的牌是否形成顺子。(我已经按升序对手牌进行了排序。)

我的解决方案

PokerHand.prototype._check_straight_function = function(arr) {
    var isStraight = false;
    for (var j = i = 4; i >= 0 && j > 1; i--)
        if (arr[i].value() - 1 == arr[--j].value()) {
            isStraight = true;
        } else {
            isStraight = false;
        }
    };
    return isStraight;
};
Run Code Online (Sandbox Code Playgroud)

其他方法

我认为可能工作得更快但没有得到工作的事情,如果有人能告诉我以下方法的工作版本并帮助我了解哪种方法评估速度最快,我将非常感激。

  • 递归使用arr.pop().value - 1 == arr.pop().value()
  • filter创建一个新数组,其中仅包含下一个索引 (arr[++i])是当前索引 + 1 的值,然后查看新数组的长度是否相同。
  • afor loop与 abreak / continue一起,一旦直端短路。

use*_*740 1

[原始]代码不正确,因为它isStraight只会为正在检查的给定对进行分配(或清除)。因此,“最后一对”错误地确定了结果。

在我的书中,“更好的方法”是保持清洁:

for (var i = 0; i < 4; i++) {
    var a = arr[i];   // arr[0..3]
    var b = arr[i+1]; // arr[1..4]
    if (!(a.value() + 1 == b.value())) {
        return false; // Not sequential
    }
};
return true;
Run Code Online (Sandbox Code Playgroud)

如果有一个zip高阶函数可用,这可以减少为

arr.zip(function (a, b) { return [a.value(), b.value()] })
   .every(function (x) { return x[0] + 1 === x[1] })
Run Code Online (Sandbox Code Playgroud)

zip不是标准的。

  • 这不是一个答案。这应该作为评论放置。 (2认同)
  • 我已经修复了错误,这取决于我编写代码来通过测试而不是解决问题。:$ 不过我确实喜欢高阶函数的想法。 (2认同)