Ich habe mich gefragt, wie ein JavaScript-Array am effizientesten gedreht werden kann.
Ich habe mir diese Lösung ausgedacht, bei der ein Positiv n
das Array nach rechts und ein Negativ n
nach links dreht ( -length < n < length
):
Array.prototype.rotateRight = function( n ) {
this.unshift( this.splice( n, this.length ) );
}
Welches kann dann so verwendet werden:
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
months.rotate( new Date().getMonth() );
Meine ursprüngliche Version oben weist einen Fehler auf, wie Christoph in den Kommentaren unten ausgeführt hat. Eine korrekte Version ist (die zusätzliche Rückgabe ermöglicht eine Verkettung):
Array.prototype.rotateRight = function( n ) {
this.unshift.apply( this, this.splice( n, this.length ) );
return this;
}
Gibt es eine kompaktere und / oder schnellere Lösung, möglicherweise im Kontext eines JavaScript-Frameworks? (Keine der vorgeschlagenen Versionen unten ist entweder kompakter oder schneller)
Gibt es ein JavaScript-Framework mit einem integrierten Array-Rotations-Framework? (Immer noch von niemandem beantwortet)
quelle
months[new Date().getMonth()]
, um den Namen des aktuellen Monats abzurufen?apply()
, damit Ihre Implementierung funktioniertDec
an erster Stelle):["Dec", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"]
Array.prototype.unshift.apply(this, this.splice(...))
- meine Version macht das gleiche, verwendet aberpush()
anstelle vonunshift()
Antworten:
Typensichere, generische Version, die das Array mutiert:
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 den Kommentaren sprach Jean das Problem an, dass der Code das Überladen von
push()
und nicht unterstütztsplice()
. Ich denke nicht, dass dies wirklich nützlich ist (siehe Kommentare), aber eine schnelle Lösung (allerdings ein bisschen wie ein Hack) wäre, die Leitung zu ersetzenpush.apply(this, splice.call(this, 0, count));
mit diesem:
(this.push || push).apply(this, (this.splice || splice).call(this, 0, count));
Die Verwendung von
unshift()
anstelle vonpush()
ist in Opera 10 fast doppelt so schnell, während die Unterschiede in FF vernachlässigbar waren. der 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; }; })();
quelle
Array.prototype
Methoden! +1apply
Methode übergeben können, bei einer bestimmten Aufrufstapelgröße begrenzt. In ES6-Begriffen würde der Spread-Operator auch unter dem gleichen Problem mit der Stapelgröße leiden. Unten gebe ich eine Kartenmethode, um das Gleiche zu tun. Es ist langsamer, funktioniert aber für Millionen von Gegenständen. Sie können die Karte auch mit einer einfachen for- oder while-Schleife implementieren, die viel schneller wird.Sie können verwendet werden
push()
,pop()
,shift()
undunshift()
Methoden:function arrayRotate(arr, reverse) { if (reverse) arr.unshift(arr.pop()); else arr.push(arr.shift()); return arr; }
Verwendung:
arrayRotate(['h','e','l','l','o']); // ['e','l','l','o','h']; arrayRotate(['h','e','l','l','o'], true); // ['o','h','e','l','l'];
Wenn Sie
count
Argumente benötigen, lesen Sie meine andere Antwort: https://stackoverflow.com/a/33451102 🖤🧡💚💙💜quelle
Ich würde wahrscheinlich so etwas machen:
Array.prototype.rotate = function(n) { return this.slice(n, this.length).concat(this.slice(0, n)); }
Bearbeiten Hier ist eine Mutator-Version:
Array.prototype.rotate = function(n) { while (this.length && n < 0) n += this.length; this.push.apply(this, this.splice(0, n)); return this; }
quelle
n = n % this.length
vor der return-Anweisung hinzugefügt , um negative und / oder außerhalb der Grenzen liegende Zahlen zu behandeln.Diese Funktion funktioniert in beide Richtungen und funktioniert mit einer beliebigen Zahl (auch mit einer Zahl, die größer als die Array-Länge ist):
function arrayRotate(arr, count) { count -= arr.length * Math.floor(count / arr.length); arr.push.apply(arr, arr.splice(0, count)); return arr; }
Verwendung:
for(let i = -6 ; i <= 6 ; i++) { console.log(arrayRotate(["🧡","💚","💙","💜","🖤"], i), i); }
Ergebnis:
[ "🖤", "🧡", "💚", "💙", "💜" ] -6 [ "🧡", "💚", "💙", "💜", "🖤" ] -5 [ "💚", "💙", "💜", "🖤", "🧡" ] -4 [ "💙", "💜", "🖤", "🧡", "💚" ] -3 [ "💜", "🖤", "🧡", "💚", "💙" ] -2 [ "🖤", "🧡", "💚", "💙", "💜" ] -1 [ "🧡", "💚", "💙", "💜", "🖤" ] 0 [ "💚", "💙", "💜", "🖤", "🧡" ] 1 [ "💙", "💜", "🖤", "🧡", "💚" ] 2 [ "💜", "🖤", "🧡", "💚", "💙" ] 3 [ "🖤", "🧡", "💚", "💙", "💜" ] 4 [ "🧡", "💚", "💙", "💜", "🖤" ] 5 [ "💚", "💙", "💜", "🖤", "🧡" ] 6
quelle
var arr2 = arrayRotate(arr.slice(0), 5)
const immutatableArrayRotate = (arr, count) => ArrayRotate(arr.clone(), count)
So viele dieser Antworten scheinen zu kompliziert und schwer zu lesen. Ich glaube nicht, dass ich jemanden gesehen habe, der Spleiß mit Concat verwendet hat ...
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-Ausgaben (* generiert im Mai):
["May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr"]
In Bezug auf die Kompaktheit kann ich einige allgemeine Einzeilerfunktionen anbieten (ohne den Teil console.log | return). Geben Sie einfach das Array und den Zielwert in die Argumente ein.
Ich kombiniere diese Funktionen zu einer für ein Kartenspielprogramm für vier Spieler, bei dem das Array ['N', 'E', 'S', 'W'] ist. Ich habe sie getrennt gelassen, falls jemand für seine Bedürfnisse kopieren / einfügen möchte. Für meine Zwecke benutze ich die Funktionen, wenn ich suche, wer an der Reihe ist, in verschiedenen Phasen des Spiels zu spielen / zu handeln (Pinochle). Ich habe mich nicht darum gekümmert, auf Geschwindigkeit zu testen. Wenn jemand anderes dies möchte, kann er mich gerne über die Ergebnisse informieren.
* Beachten Sie, der einzige Unterschied zwischen den Funktionen ist "+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; }
Kombinationsfunktion ...
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);
adjustArray =
quelle
Verwendung des ES6-Spread als unveränderliches Beispiel ...
[...array.slice(1, array.length), array[0]]
und
[array[array.items.length -1], ...array.slice(0, array.length -1)]
Es ist wahrscheinlich nicht das effizienteste, aber es ist prägnant.
quelle
Einfache Lösung mit Slice und Destructuring:
const rotate = (arr, count = 1) => { return [...arr.slice(count, arr.length), ...arr.slice(0, count)]; }; const arr = [1,2,3,4,5]; console.log(rotate(arr, 1)); // [2, 3, 4, 5, 1] console.log(rotate(arr, 2)); // [3, 4, 5, 1, 2] console.log(rotate(arr, -2)); // [4, 5, 1, 2, 3] console.log(rotate(arr, -1)); // [5, 1, 2, 3, 4]
quelle
count === 0
indem Sie einen Standardwert festlegen. Das würde es Ihnen ermöglichen, dies zu einemconst rotate = (arr, n = 1) => [...arr.slice(n, arr.length), ...arr.slice(0, n)];
Hier ist eine sehr einfache Möglichkeit, Elemente in einem Array zu verschieben:
function rotate(array, stepsToShift) { for (var i = 0; i < stepsToShift; i++) { array.unshift(array.pop()); } return array; }
quelle
@Christoph, du hast einen sauberen Code gemacht, aber 60% langsamer als dieser, den ich gefunden habe. Schauen Sie sich das Ergebnis auf jsPerf an: http://jsperf.com/js-rotate-array/2 [Bearbeiten] OK, jetzt gibt es mehr Browser und die nicht offensichtlichen Hexenmethoden am besten
var rotateArray = function(a, inc) { for (var l = a.length, inc = (Math.abs(inc) >= l && (inc %= l), inc < 0 && (inc += l), inc), i, x; inc; inc = (Math.ceil(l / inc) - 1) * inc - l + (l = inc)) for (i = l; i > inc; x = a[--i], a[i] = a[i - inc], a[i - inc] = x); return a; }; var array = ['a','b','c','d','e','f','g','h','i']; console.log(array); console.log(rotateArray(array.slice(), -1)); // Clone array with slice() to keep original
quelle
Siehe http://jsperf.com/js-rotate-array/8
function reverse(a, from, to) { --from; while (++from < --to) { var tmp = a[from]; a[from] = a[to]; a[to] = tmp; } } function rotate(a, from, to, k) { var n = to - from; k = (k % n + n) % n; if (k > 0) { reverse(a, from, from + k); reverse(a, from + k, to); reverse(a, from, to); } }
quelle
Als ich kein fertiges Snippet finden konnte, um eine Liste von Tagen mit "Heute" zu beginnen, habe ich es so gemacht (nicht ganz allgemein, wahrscheinlich weit weniger verfeinert als die obigen Beispiele, aber den Job gemacht):
//returns 7 day names with today first function startday() { const days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']; let today = new Date(); let start = today.getDay(); //gets day number if (start == 0) { //if Sunday, days are in order return days } else { //if not Sunday, start days with today return days.slice(start).concat(days.slice(0,start)) } }
Dank eines kleinen Refaktors von einem besseren Programmierer als mir ist es ein oder zwei Zeilen kürzer als mein erster Versuch, aber weitere Kommentare zur Effizienz sind willkommen.
quelle
// Example of array to rotate let arr = ['E', 'l', 'e', 'p', 'h', 'a', 'n', 't']; // Getting array length let length = arr.length; // rotation < 0 (move left), rotation > 0 (move right) let rotation = 5; // Slicing array in two parts let first = arr.slice( (length - rotation) % length, length); //['p', 'h', 'a' ,'n', 't'] let second = arr.slice(0, (length - rotation) % length); //['E', 'l', 'e'] // Rotated element let rotated = [...first, ...second]; // ['p', 'h', 'a' ,'n', 't', 'E', 'l', 'e']
In einer Codezeile:
let rotated = [...arr.slice((length - rotation) % length, length), ...arr.slice(0, (length - rotation) % length)];
quelle
Die akzeptierte Antwort weist den Fehler auf, dass Arrays, die größer als die Größe des Aufrufstapels sind, nicht verarbeitet werden können. Dies hängt von der Sitzung ab, sollte jedoch etwa 100 bis 300.000 Elemente umfassen. In der aktuellen Chrome-Sitzung, in der ich es ausprobiert habe, war es beispielsweise 250891. In vielen Fällen wissen Sie möglicherweise nicht einmal, in welche Größe das Array dynamisch hineinwachsen könnte. Das ist also ein ernstes Problem.
Um diese Einschränkung zu überwinden, besteht eine interessante Methode darin,
Array.prototype.map()
die Elemente zu verwenden und abzubilden, indem die Indizes kreisförmig neu angeordnet werden. Diese Methode verwendet ein ganzzahliges Argument. Wenn dieses Argument positiv ist, dreht es sich bei steigenden Indizes und wenn es bei abnehmender Indexrichtung negativ ist. Dies hat nur eine O (n) -Zeitkomplexität und gibt ein neues Array zurück, ohne das aufgerufene zu mutieren, während Millionen von Elementen problemlos verarbeitet werden. Mal sehen, wie es funktioniert;Array.prototype.rotate = function(n) { var len = this.length; return !(n % len) ? this : n > 0 ? this.map((e,i,a) => a[(i + n) % len]) : this.map((e,i,a) => a[(len - (len - i - n) % len) % len]); }; var a = [1,2,3,4,5,6,7,8,9], b = a.rotate(2); console.log(JSON.stringify(b)); b = a.rotate(-1); console.log(JSON.stringify(b));
Eigentlich, nachdem ich in zwei Punkten wie folgt kritisiert worden bin;
Ich habe beschlossen, den Code wie folgt zu ändern:
Array.prototype.rotate = function(n) { var len = this.length; return !(n % len) ? this.slice() : this.map((e,i,a) => a[(i + (len + n % len)) % len]); }; var a = [1,2,3,4,5,6,7,8,9], b = a.rotate(10); console.log(JSON.stringify(b)); b = a.rotate(-10); console.log(JSON.stringify(b));
Dann wieder; Natürlich sind die JS-Funktoren
Array.prototype.map()
im Vergleich zu ihren in einfachem JS codierten Äquivalenten langsam. Um mehr als 100% Leistungssteigerung zu erzielen, würde ich wahrscheinlich Folgendes wählen,Array.prototype.rotate()
wenn ich jemals ein Array im Produktionscode drehen muss, wie ich es bei meinem Versuch verwendet habeString.prototype.diff()
Array.prototype.rotate = function(n){ var len = this.length, res = new Array(this.length); if (n % len === 0) return this.slice(); else for (var i = 0; i < len; i++) res[i] = this[(i + (len + n % len)) % len]; return res; };
quelle
Diese Funktion ist etwas schneller als die akzeptierte Antwort für kleine Arrays, aber viel schneller für große Arrays. Diese Funktion ermöglicht auch eine beliebige Anzahl von Umdrehungen, die größer als die Länge des Arrays sind, was eine Einschränkung der ursprünglichen Funktion darstellt.
Zuletzt dreht sich die akzeptierte Antwort wie beschrieben in die entgegengesetzte Richtung.
const rotateForEach = (a, n) => { const l = a.length; a.slice(0, -n % l).forEach(item => a.push( item )); return a.splice(n % l > 0 ? (-n % l) : l + (-n % l)); }
Und das funktionale Äquivalent (das auch einige Leistungsvorteile zu haben scheint):
const rotateReduce = (arr, n) => { const l = arr.length; return arr.slice(0, -n % l).reduce((a,b) => { a.push( b ); return a; }, arr).splice(n % l> 0 ? l + (-n % l) : -n % l); };
Die Leistungsaufschlüsselung können Sie hier einsehen.
quelle
EDIT :: Hey, es stellt sich heraus, dass zu viel Iteration passiert. Keine Schleifen, keine Verzweigung.
Funktioniert immer noch mit negativem n für Rechtsdrehung und positivem n für Linksdrehung für jede Größe n, mutationsfrei
function rotate(A,n,l=A.length) { const offset = (((n % l) + l) %l) return A.slice(offset).concat(A.slice(0,offset)) }
Hier ist die Code-Golf-Version für Kichern
const r = (A,n,l=A.length,i=((n%l)+l)%l)=>A.slice(i).concat(A.slice(0,i))
EDIT1 :: * Branchless, mutationsless Implementierung.
Es stellte sich heraus, dass ich einen Zweig hatte, in dem ich ihn nicht brauchte. Hier ist eine funktionierende Lösung. negative num = rechts um | num | drehen positive num = links um num drehen
function r(A,n,l=A.length) { return A.map((x,i,a) => A[(((n+i)%l) + l) % l]) }
Die Gleichung
((n%l) + l) % l
bildet genau positive und negative Zahlen beliebig großer Werte von n abORIGINAL
Nach links und rechts drehen. Mit positiv nach links
n
drehen, mit negativ nach rechts drehenn
.Funktioniert für obszön große Eingaben von
n
.Kein Mutationsmodus. Zu viele Mutationen in diesen Antworten.
Außerdem weniger Operationen als die meisten Antworten. Kein Pop, kein Push, kein Spleiß, keine Verschiebung.
const rotate = (A, num ) => { return A.map((x,i,a) => { const n = num + i return n < 0 ? A[(((n % A.length) + A.length) % A.length)] : n < A.length ? A[n] : A[n % A.length] }) }
oder
const rotate = (A, num) => A.map((x,i,a, n = num + i) => n < 0 ? A[(((n % A.length) + A.length) % A.length)] : n < A.length ? A[n] : A[n % A.length]) //test rotate([...Array(5000).keys()],4101) //left rotation rotate([...Array(5000).keys()],-4101000) //right rotation, num is negative // will print the first index of the array having been rotated by -i // demonstrating that the rotation works as intended [...Array(5000).keys()].forEach((x,i,a) => { console.log(rotate(a,-i)[0]) }) // prints even numbers twice by rotating the array by i * 2 and getting the first value //demonstrates the propper mapping of positive number rotation when out of range [...Array(5000).keys()].forEach((x,i,a) => { console.log(rotate(a,i*2)[0]) })
Erläuterung:
Ordnen Sie jeden Index von A dem Wert am Indexversatz zu. In diesem Fall
wenn das
offset < 0
dannoffset + index + positive length of A
auf den inversen Versatz zeigt.wenn
offset > 0 and offset < length of A
dann, ordnen Sie einfach den aktuellen Index dem Offset-Index von A zu.Andernfalls modulo den Versatz und die Länge, um den Versatz in den Grenzen des Arrays abzubilden.
Nehmen Sie zum Beispiel
offset = 4
undoffset = -4
.Wann
offset = -4
undA = [1,2,3,4,5]
für jeden Indexoffset + index
wird die Größe (oderMath.abs(offset)
) kleiner.Lassen Sie uns zuerst die Berechnung für den Index des negativen n erklären.
A[(((n % A.length) + A.length) % A.length)+0]
und eingeschüchtert worden. Sei nicht. Ich habe 3 Minuten in einem Repl gebraucht, um das herauszufinden.n
es negativ ist, weil der Fall istn < 0
. Wenn die Zahl größer als der Bereich des Arrays ist,n % A.length
wird sie dem Bereich zugeordnet.n + A.length
Addiere diese Zahl zuA.length
, um n den richtigen Betrag auszugleichen.n
es negativ ist, weil der Fall istn < 0
.n + A.length
Addiere diese Zahl zuA.length
, um n den richtigen Betrag auszugleichen.Weiter Ordnen Sie es mit Modulo dem Längenbereich von A zu. Das zweite Modul ist erforderlich, um das Ergebnis der Berechnung in einen indizierbaren Bereich abzubilden
Erster Index: -4 + 0 = -4. A. Länge = 5. A. Länge - 4 = 1. A 2 ist 2. Kartenindex 0 bis 2.
[2,... ]
[2,3... ]
Der gleiche Prozess gilt für
offset = 4
. Wannoffset = -4
undA = [1,2,3,4,5]
für jeden Indexoffset + index
wird die Größe größer.4 + 0 = 0
. Ordnen Sie A [0] dem Wert bei A [4] zu.[5...]
4 + 1 = 5
, 5 ist beim Indizieren außerhalb der Grenzen, also ordne A 2 dem Wert am Rest von zu5 / 5
, der 0 ist. A 2 = Wert bei A [0].[5,1...]
quelle
function rotate(arr, k) { for (var i = 0; i < k+1; i++) { arr.push(arr.shift()); } return arr; } //k work as an index array console.log(rotate([1, 2, 7, 4, 5, 6, 7], 3)); //[5,6,7,1,2,7,4] console.log(rotate([-1, -100, 3, 99], 2)); //[99,-1,-100,3]
quelle
Follow a simpler approach of running a loop to n numbers and shifting places upto that element. function arrayRotateOne(arr, n) { for (let i = 0; i < n; i++) { arr.unshift(arr.pop()); } return arr; } console.log( arrayRotateOne([1,2,3,4,5,6],2)); function arrayRotateOne(arr,n) { for(let i=0; i<n;i++){ arr.push(arr.shift()); console.log('execute',arr) } return arr; }
console.log (arrayRotateOne ([1,2,3,4,5,6], 2));
quelle
Nicht mutierende Lösung
var arr = ['a','b','c','d'] arr.slice(1,arr.length).concat(arr.slice(0,1)
mit Mutation
var arr = ['a','b','c','d'] arr = arr.concat(arr.splice(0,1))
quelle
Ich teile meine Lösung, die ich zum Drehen auf einem Karussell verwende. Es kann zu Unterbrechungen kommen, wenn die Arraygröße kleiner als
displayCount
ist. Sie können jedoch eine zusätzliche Bedingung hinzufügen, um die Rotation zu stoppen, wenn sie klein ist, oder das Hauptarray zu verketten.function rotate(arr, moveCount, displayCount) { const size = arr.length; // making sure startIndex is between `-size` and `size` let startIndex = moveCount % size; if (startIndex < 0) startIndex += size; return [...arr, ...arr].slice(startIndex, startIndex + displayCount); } // move 3 to the right and display 4 items // rotate([1,2,3,4,5], 3, 4) -> [4,5,1,2] // move 3 to the left and display 4 items // rotate([1,2,3,4,5], -3, 4) -> [3,4,5,1] // move 11 to the right and display 4 // rotate([1,2,3,4,5], 3, 4) -> [2,3,4,5]
quelle
Wie wäre es, wenn Sie einen Zähler erhöhen und dann den Rest einer Division durch die Array-Länge abrufen, um zu erreichen, wo Sie sein sollen.
var i = 0; while (true); { var position = i % months.length; alert(months[position]); ++i; }
Abgesehen von der Sprachsyntax sollte dies gut funktionieren.
quelle
Wenn Ihr Array groß sein wird und / oder Sie sich viel drehen werden, sollten Sie eine verknüpfte Liste anstelle eines Arrays verwenden.
quelle
@molokoloco Ich brauchte eine Funktion, die ich so konfigurieren konnte, dass sie sich in eine Richtung dreht - wahr für vorwärts und falsch für rückwärts. Ich habe ein Snippet erstellt, das eine Richtung, einen Zähler und ein Array annimmt und ein Objekt ausgibt, wobei der Zähler in die entsprechende Richtung erhöht wird sowie vorherige, aktuelle und nächste Werte. Das ursprüngliche Array wird NICHT geändert.
Ich habe es auch gegen Ihr Snippet getaktet und obwohl es nicht schneller ist, ist es schneller als die, mit denen Sie es vergleichen - 21% langsamer http://jsperf.com/js-rotate-array/7 .
function directionalRotate(direction, counter, arr) { counter = direction ? (counter < arr.length - 1 ? counter + 1 : 0) : (counter > 0 ? counter - 1 : arr.length - 1) var currentItem = arr[counter] var priorItem = arr[counter - 1] ? arr[counter - 1] : arr[arr.length - 1] var nextItem = arr[counter + 1] ? arr[counter + 1] : arr[0] return { "counter": counter, "current": currentItem, "prior": priorItem, "next": nextItem } } var direction = true // forward var counter = 0 var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']; directionalRotate(direction, counter, arr)
quelle
Ich komme zu spät, aber ich muss diesen guten Antworten einen Stein hinzufügen. Ich wurde gebeten, eine solche Funktion zu codieren, und ich tat es zuerst:
Array.prototype.rotate = function(n) { for (var i = 0; i < n; i++) { this.push(this.shift()); } return this; }
Aber es schien weniger effizient zu sein als zu folgen, wenn
n
es groß ist:Array.prototype.rotate = function(n) { var l = this.length;// Caching array length before map loop. return this.map(function(num, index) { return this[(index + n) % l] }); }
quelle
Ich bin mir nicht sicher, ob dies der effizienteste Weg ist, aber ich mag die Art und Weise, wie er gelesen wird. Er ist schnell genug für die meisten großen Aufgaben, da ich ihn in der Produktion getestet habe ...
function shiftRight(array) { return array.map((_element, index) => { if (index === 0) { return array[array.length - 1] } else return array[index - 1] }) } function test() { var input = [{ name: '' }, 10, 'left-side']; var expected = ['left-side', { name: '' }, 10] var actual = shiftRight(input) console.log(expected) console.log(actual) } test()
quelle
Native, schnell, klein, semantisch, arbeitet an alten Motoren und "curryable".
function rotateArray(offset, array) { offset = -(offset % array.length) | 0 // ensure int return array.slice(offset).concat( array.slice(0, offset) ) }
quelle
** Mit der neuesten Version von JS können wir es ganz einfach erstellen **
Array.prototype.rotateLeft = function (n) { this.unshift(...this.splice(-(n), n)); return this }
Hier bewegt sich: Anzahl der Umdrehungen , ein Array , das Sie Zufallszahl übergeben können
let a = [1, 2, 3, 4, 5, 6, 7]; let moves = 4; let output = a.rotateLeft(moves); console.log("Result:", output)
quelle
Array
In JS ist unten eine Methode eingebaut, mit der ein Array ganz einfach gedreht werden kann, und offensichtlich sind diese Methoden von Natur aus unveränderlich .push
: Fügt das Element am Ende des Arrays ein.pop
: Entfernt das Element vom Ende des Arrays.unshift
: Fügt das Element am Anfang des Arrays ein.shift
: Entfernt das Element vom Anfang des Arrays.Die folgende Lösung (
ES6
) verwendet zwei Argumente: Das Array muss gedreht werden und n, wie oft das Array gedreht werden soll.const rotateArray = (arr, n) => { while(arr.length && n--) { arr.unshift(arr.pop()); } return arr; } rotateArray(['stack', 'overflow', 'is', 'Awesome'], 2) // ["is", "Awesome", "stack", "overflow"]
Es kann zu Array.prototype hinzugefügt und in Ihrer gesamten Anwendung verwendet werden
Array.prototype.rotate = function(n) { while(this.length && n--) { this.unshift(this.pop()); } return this; } [1,2,3,4].rotate(3); //[2, 3, 4, 1]
quelle
Verwenden der for-Schleife. Hier sind die Schritte
function rotateLeft(arr, rotations) { let len = arr.length; for(let i=0; i<rotations; i++){ let temp = arr[0]; for(let i=0; i< len; i++){ arr[i]=arr[i+1]; } arr[len-1]=temp; } return arr; } let arr = [1,2,3,4,5]; let rotations = 3; let output = rotateLeft(arr, rotations); console.log("Result Array => ", output);
quelle
mit es6-Syntax
function rotLeft(a, d) { const removed = a.splice(0,d); return [...a, ...removed]; }
quelle
Ich bin mir nicht sicher über die Effizienz, aber ich würde es auf diese nicht mutierende Weise tun:
quelle