1. ホーム
  2. javascript

[解決済み] JavaScriptで配列の要素を回転させる

2022-02-25 20:14:17

質問

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のフレームワークで、配列回転を内蔵しているものはありますか?(まだ誰からも回答がありません)

どのように解決するのですか?

配列を変異させるタイプセーフな汎用版。

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() . これはあまり意味がないと思うのですが(コメント参照)、手っ取り早い解決策(多少ハックされますが)は、次の行を置き換えることでしょう。

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

をこれを使って

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


使用方法 unshift() の代わりに push() は、Opera 10では約2倍の速さですが、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;
    };
})();