So kehren Sie Arrays in JavaScript um, ohne .reverse () zu verwenden

In-Place & Out-of-Place

Foto von Guillaume Bolduc auf Unsplash

Eine typische JavaScript-Herausforderung oder Interviewfrage hat mit der In-Place- und Out-of-Place-Umkehrung von Arrays zu tun. Nehmen Sie speziell dieses Problem von Eloquent JavaScript, 2nd Edition:

Schreiben Sie zwei Funktionen reverseArray und reverseArrayInPlace. Das erste, reverseArray, nimmt ein Array als Argument und erzeugt ein neues Array, das dieselben Elemente in umgekehrter Reihenfolge enthält. Die zweite Methode, reverseArrayInPlace, führt die umgekehrte Methode aus: Sie ändert das als Argument angegebene Array, um seine Elemente umzukehren. Weder darf die Standard-Reverse-Methode verwenden.

Das ist der Kicker: Sie können die .reverse () -Methode nicht verwenden.

Ich habe dieses Problem in der Vergangenheit durchgearbeitet, aber jetzt, da ich nach einer Pause wieder JavaScript lerne, habe ich eine Weile gebraucht, um meinen Kopf wieder darum zu wickeln. Besonders das Umkehren des Arrays vor Ort. Um dieses Problem besser zu verstehen und zu durchdenken, habe ich mich entschlossen, diesen Artikel zu schreiben.

Umkehren eines fehl am Platz befindlichen Arrays

Lassen Sie uns zunächst zwei Arrays erstellen:

var array1 = ["ja", "nein", "vielleicht", "immer", "manchmal", "nie", "wenn"];
var array2 = [5,8,2,9,5,6,3,1];

Wenn wir für die reverseArray-Funktion ein neues Array erstellen möchten, benötigen wir ein leeres Array, um es später aufzufüllen:

var newArray = [];

Schreiben Sie die Schritte in Pseudocode:

// 1) Ich möchte das letzte Element des Arrays nehmen und es dann zum newArray hinzufügen.
// 2) Dazu muss ich das Array vom Ende bis zum Anfang durchlaufen, da das letzte Element zuerst sein soll.
// 3) Ich möchte den Inhalt von 'newArray' ausgeben, wenn die for-Schleife beendet ist.

Lassen Sie uns zuerst unsere for-Schleife ausarbeiten. Um am Ende des Arrays zu beginnen, wollen wir i gleich der Länge des Arrays minus 1 setzen, da der Index eines Arrays immer bei Null beginnt.

var i = array.length - 1

Beispielsweise würde array1.length 7 ergeben, da sieben Elemente enthalten sind. Der Index von jedem ist jedoch 0, 1, 2, 3, 4, 5 und 6. Um also bei dem Element mit einem Index von 6 zu beginnen, müssten wir die Länge des Arrays nehmen und 1 subtrahieren .

Wenn wir unsere vollständige for-Schleife ausschreiben, erhalten wir:

für (var i = arr.length - 1; i> = 0; i--)

Mit anderen Worten, wir subtrahieren mit jeder Schleife 1 vom Index, bis i größer oder gleich 0 ist, dem Anfang des Arrays. (Das Verwenden von arr als Parametername in der folgenden Funktion ist dasselbe wie das Verwenden von array. Lassen Sie sich davon nicht abbringen!)

Funktion reverseArray (arr) {
  var newArray = [];
  für (var i = arr.length - 1; i> = 0; i--) {
    newArray.push (arr [i]);
  }
  return newArray;
}

arr [i] repräsentiert jedes Element an seinem jeweiligen Index. Bei der ersten Schleife ist arr [i] das Element "if". In jeder Schleife verwenden wir die .push () -Methode, um arr [i] wörtlich an das Ende des newArray zu "pushen".

Wenn Sie array1 an diese Funktion übergeben, erhalten Sie:

reverseArray (array1)
⊳ ["wenn", "nie", "manchmal", "immer", "vielleicht", "nein", "ja"]

In-Place-Umkehrung eines Arrays

Die Dinge werden für mich sofort komplizierter, wenn ich versuche, ein Array an Ort und Stelle umzukehren. Als ich anfänglich versuchte, dieses Problem zu lösen, versuchte ich, das erste Element mit .shift () zu erfassen, indem ich es auf eine Variable mit dem ersten Namen einstellte und dann mit .push () an das Ende des ursprünglichen Arrays anfügte. Aber das Problem, auf das ich gestoßen bin, ist, dass ich nur das erste und das letzte Element bei jeder Schleife immer wieder umgedreht habe, weil .shift () nur Elemente am ‘Zeroeth Index’ und .pop () am letzten entfernt.

Es gab auch das Problem, wo die for-Schleife zu starten und zu beenden ist.

Bevor wir jedoch fortfahren, schreiben wir das Problem in Pseudocode:

// 1) Ich weiß, dass ich das Array durchlaufen muss. Aber bevor ich herausfinde, wo ich anfangen oder enden soll, muss ich darüber nachdenken, wie ich die Elemente im Array tatsächlich umkehren werde.
// 2) Die einzige Möglichkeit, dies zu tun, besteht darin, das erste Element mit dem letzten Element und dann das zweite Element mit dem vorletzten Element usw. zu vertauschen, bis ich in der Mitte angelangt bin.

Im Sinne unserer for-Schleife kann ich also am Anfang oder Ende des Arrays beginnen und enden, wenn ich die halbe Länge des Arrays habe.

Die Art und Weise, wie ich dies ursprünglich dachte, war:

für (var i = 0; i <= (arr.length / 2); i ++)

Dann setze ich das erste Element gleich einer Variablen namens el, dann setze ich das erste Element gleich dem letzten und das letzte gleich dem ersten (el).

So sieht es aus:

sei el = arr [i];
arr [i] = arr [arr.length - 1 - i];
arr [arr.length - 1 - i] = el;

Mit jeder Schleife würde el zurückgesetzt, um dem nächsten Element im Array zu entsprechen.

arr [arr.length - 1 - i] ist nur eine Art zu sagen:

  1. In der ersten Schleife ist der Index die Länge des Arrays minus 1 minus dem Wert von i, der 0 ist. Am Beispiel von Array1 wäre dies: 8 - 1 - 0 = 7. arr [7] is das letzte Element von array1, das "if" ist.
  2. In der zweiten Schleife wäre dies: 8 - 1 - 1 = 6. Daher wäre arr [6] das vorletzte Element von array1, das "never" ist. Immer weiter, bis die Mitte des Arrays erreicht ist.

Wenn Sie es so versuchen, sieht es so aus:

Funktion reverseArrayInPlace (arr) {
  für (var i = 0; i <= (arr.length / 2); i ++) {
      sei el = arr [i];
      arr [i] = arr [arr.length - 1 - i];
      arr [arr.length - 1 - i] = el;
  }
  return arr;
}

Aber beim Testen passiert etwas Seltsames mit Arrays, die eine gerade Länge haben, wie z. B. array2:

reverseArrayInPlace (array2)
⊳ [1, 3, 6, 9, 5, 2, 8, 5]

9 und 5 sind in der Mitte vertauscht!

In Fällen, in denen unser Array eine ungerade Zahl ist, wie Array1, würde die Verwendung von i <= (arr.length / 2) funktionieren, da Array1.length 3.5 ist und die Schleife fortgesetzt wird, solange i kleiner oder gleich 3.5 ist . Wenn unsere Länge jedoch 8 ist, wie es in Array 2 der Fall ist, stoppt die Schleife bei Index 4, der tatsächlich 1 Index hinter dem Punkt liegt, an dem wir anhalten möchten. Da der Index bei 0 beginnt, möchten wir eigentlich bei 3 anhalten.

Um dies zu beheben, können wir 1 von der Länge des Arrays subtrahieren, bevor wir es durch 2 dividieren. Für ein gutes Maß können wir Math.floor vorziehen, um Dezimalstellen auf die nächste ganze Zahl abzurunden.

Funktion reverseArrayInPlace (arr) {
  für (var i = 0; i <= Math.floor ((arr.length - 1) / 2); i ++) {
      sei el = arr [i];
      arr [i] = arr [arr.length - 1 - i];
      arr [arr.length - 1 - i] = el;
  }
  return arr;
}

Zur Überprüfung:

  • Wir haben am Anfang des Arrays in unserer for-Schleife begonnen.
  • Wir gingen durch die Reihe, bis wir den halben Punkt erreichten.
  • Bei jeder Schleife setzen wir das Element auf i - oder arr [i] - gleich einer Variablen mit dem Namen el.
  • Dann setzen wir das erste Element gleich dem letzten und das letzte Element gleich dem ersten.
  • Bei jeder folgenden Schleife haben wir, während wir uns nach innen bewegten, dasselbe getan.

Ich bin ein JavaScript-Neuling. Wenn Sie also eine effizientere Möglichkeit haben, würde ich mich freuen, wenn Sie im Kommentarbereich unten von Ihnen hören!

Funktion letsConnect (yes) {
  if (yes === true) {
    console.log ("linkedIn");
    console.log ("Twitter");
  } else {
    console.log ("Danke fürs Lesen!");
  }
}