JavaScript的数组旋转()(JavaScript Array rotate())

2019-10-22 18:44发布

我想知道什么是旋转的最有效方法的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框架在那里? (还没被任何人回答)

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

在评论,让提出这个问题的代码不支持重载push()splice() 我不认为这是非常有用的(见注释),但一个快速的解决方案(一劈有点的,虽然)将取代线

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


Answer 2:

您可以使用push() pop() shift()unshift()方法:

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

用法:

arrayRotate(['h','e','l','l','o']);       // ['e','l','l','o','h'];
arrayRotate(['h','e','l','l','o'], true); // ['o','h','e','l','l'];

如果你需要count参数看到我的其他答案: https://stackoverflow.com/a/33451102



Answer 3:

我可能会做这样的事情:

Array.prototype.rotate = function(n) {
    return this.slice(n, this.length).concat(this.slice(0, n));
}

编辑这里有一个突变版本:

Array.prototype.rotate = function(n) {
    while (this.length && n < 0) n += this.length;
    this.push.apply(this, this.splice(0, n));
    return this;
}


Answer 4:

此函数工作在两个方式,并与任何数量的工作(即使具有比阵列长数大于):

function arrayRotate(arr, count) {
  count -= arr.length * Math.floor(count / arr.length);
  arr.push.apply(arr, arr.splice(0, count));
  return arr;
}

用法:

for(let i = -6 ; i <= 6 ; i++) {
  console.log(arrayRotate(["