在 JavaScript 中旋转数组中的元素

新手上路,请多包涵

我想知道旋转 JavaScript 数组的最有效方法是什么。

我想出了这个解决方案,其中正数 n 将数组向右旋转,负数 n 向左旋转( -length < n < length

 Array.prototype.rotateRight = function( n ) {
  this.unshift( this.splice( n, this.length ) );
}

然后可以这样使用:

 var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
months.rotate( new Date().getMonth() );

我上面的原始版本有一个缺陷,正如 Christoph 在下面的评论中指出的那样,正确的版本是(附加返回允许链接):

 Array.prototype.rotateRight = function( n ) {
  this.unshift.apply( this, this.splice( n, this.length ) );
  return this;
}

是否有更紧凑和/或更快的解决方案,可能在 JavaScript 框架的上下文中? (下面的建议版本都不是更紧凑或更快)

有没有内置数组旋转的 JavaScript 框架? (仍然没有人回答)

原文由 Jean Vincent 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 421
2 个回答

改变数组的类型安全的通用版本:

 Array.prototype.rotate = (function() {
    // save references to array functions to make lookup faster
    var push = Array.prototype.push,
        splice = Array.prototype.splice;

    return function(count) {
        var len = this.length >>> 0, // convert to uint
            count = count >> 0; // convert to int

        // convert count to value in range [0, len)
        count = ((count % len) + len) % len;

        // use splice.call() instead of this.splice() to make function generic
        push.apply(this, splice.call(this, 0, count));
        return this;
    };
})();

在评论中,Jean 提出了代码不支持重载 push()splice() 的问题。我不认为这真的有用(见评论),但一个快速的解决方案(虽然有点 hack)是替换这条线

push.apply(this, splice.call(this, 0, count));

有了这个:

 (this.push || push).apply(this, (this.splice || splice).call(this, 0, count));


使用 unshift() 而不是 push() 在 Opera 10 中几乎快两倍,而 FF 中的差异可以忽略不计;编码:

 Array.prototype.rotate = (function() {
    var unshift = Array.prototype.unshift,
        splice = Array.prototype.splice;

    return function(count) {
        var len = this.length >>> 0,
            count = count >> 0;

        unshift.apply(this, splice.call(this, count % len, len));
        return this;
    };
})();

原文由 Christoph 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以使用 push()pop()shift() unshift()

 function arrayRotate(arr, reverse) {
  if (reverse) arr.unshift(arr.pop());
  else arr.push(arr.shift());
  return arr;
}

用法:

 arrayRotate([1, 2, 3, 4, 5]);       // [2, 3, 4, 5, 1];
arrayRotate([1, 2, 3, 4, 5], true); // [5, 1, 2, 3, 4];

如果您需要 count 参数,请参阅我的其他答案:

https://stackoverflow.com/a/33451102🖤🧡💚💙💜

原文由 Yukulélé 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题