小编典典

旋转JavaScript中数组中的元素

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() );

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

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

是否有可能在JavaScript框架中更紧凑和/或更快速的解决方案?(以下任何一种建议的版本都不会更紧凑或更快速)

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


阅读 311

收藏
2020-04-25

共1个答案

小编典典

类型安全的通用版本,可更改数组:

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()and的重载的问题splice()。我不认为这真的有用(请参阅评论),但是一种快速的解决方案(虽然有点hack)将替换该行

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

与此:

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

在Opera 10中,使用unshift()而不是push()几乎快一倍,而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;
    };
})();
2020-04-25