Rotate The Elements In An Array In JavaScript
Solution 1:
You can use push()
, pop()
, shift()
and unshift()
methods:
function arrayRotate(arr, reverse) {
if (reverse) arr.unshift(arr.pop());
else arr.push(arr.shift());
return arr;
}
usage:
arrayRotate([1, 2, 3, 4, 5]); // [2, 3, 4, 5, 1];
arrayRotate([1, 2, 3, 4, 5], true); // [5, 1, 2, 3, 4];
If you need count
argument see my other answer:
https://stackoverflow.com/a/33451102 π€π§‘πππ
Solution 2:
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;
};
})();
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));
with this one:
(this.push || push).apply(this, (this.splice || splice).call(this, 0, count));
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;
};
})();
Solution 3:
I would probably do something like this:
Array.prototype.rotate = function(n) {
n = n % this.length;
return this.slice(n, this.length).concat(this.slice(0, n));
}
Edit Hereβs a mutator version:
Array.prototype.rotate = function(n) {
n = n % this.length;
while (this.length && n < 0) n += this.length;
this.push.apply(this, this.splice(0, n));
return this;
}
Solution 4:
This function works in both way and works with any number (even with number greater than array length):
function arrayRotate(arr, count) {
count -= arr.length * Math.floor(count / arr.length);
arr.push.apply(arr, arr.splice(0, count));
return arr;
}
usage:
for(let i = -6 ; i <= 6 ; i++) {
console.log(arrayRotate(["π§‘","π","π","π","π€"], i), i);
}
result:
[ "π€", "π§‘", "π", "π", "π" ] -6
[ "π§‘", "π", "π", "π", "π€" ] -5
[ "π", "π", "π", "π€", "π§‘" ] -4
[ "π", "π", "π€", "π§‘", "π" ] -3
[ "π", "π€", "π§‘", "π", "π" ] -2
[ "π€", "π§‘", "π", "π", "π" ] -1
[ "π§‘", "π", "π", "π", "π€" ] 0
[ "π", "π", "π", "π€", "π§‘" ] 1
[ "π", "π", "π€", "π§‘", "π" ] 2
[ "π", "π€", "π§‘", "π", "π" ] 3
[ "π€", "π§‘", "π", "π", "π" ] 4
[ "π§‘", "π", "π", "π", "π€" ] 5
[ "π", "π", "π", "π€", "π§‘" ] 6
Solution 5:
So many of these answers seem over-complicated and difficult to read. I don't think I saw anyone using splice with concat...
function rotateCalendar(){
var cal=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
cal=cal.concat(cal.splice(0,new Date().getMonth()));
console.log(cal); // return cal;
}
console.log outputs (*generated in May):
["May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr"]
As for compactness, I can offer a couple of generic one-liner functions (not counting the console.log | return portion). Just feed it the array and the target value in the arguments.
I combine these functions into one for a four-player card game program where the array is ['N','E','S','W']. I left them separate in case anyone wants to copy/paste for their needs. For my purposes, I use the functions when seeking whose turn is next to play/act during different phases of the game (Pinochle). I haven't bothered testing for speed, so if someone else wants to, feel free to let me know the results.
*notice, the only difference between functions is the "+1".
function rotateToFirst(arr,val){ // val is Trump Declarer's seat, first to play
arr=arr.concat(arr.splice(0,arr.indexOf(val)));
console.log(arr); // return arr;
}
function rotateToLast(arr,val){ // val is Dealer's seat, last to bid
arr=arr.concat(arr.splice(0,arr.indexOf(val)+1));
console.log(arr); // return arr;
}
combination function...
function rotateArray(arr,val,pos){
// set pos to 0 if moving val to first position, or 1 for last position
arr=arr.concat(arr.splice(0,arr.indexOf(val)+pos));
return arr;
}
var adjustedArray=rotateArray(['N','E','S','W'],'S',1);
adjustedArray=
W,N,E,S
Post a Comment for "Rotate The Elements In An Array In JavaScript"