旋转JavaScript中数组中的元素 [英] Rotate the elements in an array in JavaScript

查看:66
本文介绍了旋转JavaScript中数组中的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was wondering what was the most efficient way to rotate a JavaScript array.

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

I came up with this solution, where a positive n rotates the array to the right, and a negative n to the left (-length < n < length) :

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

然后可以通过以下方式使用:

Which can then be used this way:

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

我上面的原始版本有一个缺陷,正如下面的注释中 Christoph 所指出的那样,正确的版本是(额外的收益允许链接):

My original version above has a flaw, as pointed out by Christoph in the comments bellow, a correct version is (the additional return allows chaining):

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

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

Is there a more compact and/or faster solution, possibly in the context of a JavaScript framework? (none of the proposed versions bellow is either more compact or faster)

是否存在带有内置数组旋转功能的JavaScript框架? (仍然没有任何人回答)

Is there any JavaScript framework out there with an array rotate built-in? (Still not answered by anyone)

推荐答案

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

Type-safe, generic version which mutates the array:

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)将替换该行

In the comments, Jean raised the issue that the code doesn't support overloading of push() and splice(). I don't think this is really useful (see comments), but a quick solution (somewhat of a hack, though) would be to replace the line

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的差异可以忽略不计.代码:


Using unshift() instead of push() is nearly twice as fast in Opera 10, whereas the differences in FF were negligible; the code:

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

这篇关于旋转JavaScript中数组中的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆