wake-up-neo.com

ist es möglich, die Werte des Arrays zu ändern, wenn Sie foreach in Javascript verwenden?

beispiel:

var arr = ["one","two","three"];

arr.forEach(function(part){
  part = "four";
  return "four";
})

alert(arr);

Das Array hat immer noch seine ursprünglichen Werte. Gibt es eine Möglichkeit, Schreibzugriff auf die Elemente des Arrays durch die Iterationsfunktion zu haben?

200
rsk82

Dem Callback werden das Element, der Index und das Array selbst übergeben.

arr.forEach(function(part, index, theArray) {
  theArray[index] = "hello world";
});

edit - Wie in einem Kommentar angegeben, kann die Funktion .forEach() ein zweites Argument enthalten, das als Wert von this in jedem Aufruf des Rückrufs verwendet wird:

arr.forEach(function(part, index) {
  this[index] = "hello world";
}, arr); // use arr as this

Dieses zweite Beispiel zeigt, dass arr selbst im Callback als this eingerichtet ist. Man könnte denken, dass das Array, das am Aufruf von .forEach() beteiligt ist, der default - Wert von this sein könnte, aber aus irgendeinem Grund ist dies nicht der Fall. this ist undefined, wenn das zweite Argument nicht angegeben wird.

Denken Sie auch daran, dass der Array-Prototyp eine ganze Reihe ähnlicher Dienstprogramme enthält und viele Fragen zu Stackoverflow über die eine oder andere Funktion auftauchen, sodass die beste Lösung einfach ein anderes Werkzeug ist. Du hast:

  • forEach, um etwas mit oder zu jedem Eintrag in einem Array zu tun;
  • filter zum Erzeugen eines neuen Arrays, das nur qualifizierte Einträge enthält;
  • map für die Erstellung eines neuen 1: 1-Arrays durch Transformation eines vorhandenen Arrays;
  • some, um zu prüfen, ob mindestens ein Element in einem Array zu einer Beschreibung passt.
  • every, um zu prüfen, ob all -Einträge in einem Array mit einer Beschreibung übereinstimmen;
  • find, um nach einem Wert in einem Array zu suchen

und so weiter. MDN-Link

316
Pointy

Lassen Sie uns try, um es einfach zu halten, und diskutieren, wie es tatsächlich funktioniert. Es hat mit Variablentypen und Funktionsparametern zu tun.

Hier ist dein Code, über den wir sprechen:

var arr = ["one","two","three"];

arr.forEach(function(part) {
  part = "four";
  return "four";
})

alert(arr);

Zunächst einmal sollten Sie hier etwas über Array.prototype.forEach () lesen:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Zweitens wollen wir kurz über Werttypen in JavaScript sprechen.

Primitives (undefined, null, String, Boolean, Number) speichern einen tatsächlichen Wert.

zB: var x = 5;

Referenztypen (benutzerdefinierte Objekte) speichern den Speicherort des Objekts.

zB: var xObj = { x : 5 };

Und drittens, wie Funktionsparameter funktionieren.

In Funktionen werden Parameter always per Wert übergeben.

Da arr ein Array von Strings ist, handelt es sich um ein Array von primitive - Objekten. Dies bedeutet, dass sie nach Wert gespeichert werden.

Für Ihren Code oben bedeutet dies, dass jedes Mal, wenn forEach () iteriert, part dem gleichen Wert wie arr[index], entspricht, jedoch nicht dasselbe Objekt.

part = "four"; ändert die Variable part, lässt jedoch arr unverändert.

Der folgende Code ändert die gewünschten Werte:

var arr = ["one","two","three"];

arr.forEach(function(part, index) {
  arr[index] = "four";
});

alert(arr);

Wenn Array arr jetzt ein Array von referenztypen war, funktioniert der folgende Code, da Referenztypen einen Speicherort eines Objekts anstelle des eigentlichen Objekts speichern.

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];

arr.forEach(function(part, index) {
  // part and arr[index] point to the same object
  // so changing the object that part points to changes the object that arr[index] points to

  part.num = "four";
});

alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);

Das folgende Beispiel veranschaulicht, dass Sie part so ändern können, dass es auf ein neues Objekt zeigt, während die Objekte in arr allein gespeichert bleiben:

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];

arr.forEach(function(part, index) {
  // the following will not change the object that arr[index] points to because part now points at a new object
  part = 5;
});

alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);
104
Dave

Array: ["1", 2, 3, 4]
Ergebnis: ["foo1", "foo2", "foo3", "foo4"]

Array.prototype.map() Originalarray beibehalten

erreicht durch die Einführung einer neuen Variablen modifiedArr

var arr = ["1", 2, 3, 4];

var modifiedArr = arr.map(function(v) {
  return "foo"+ v;
});

console.log( "Original:", arr );
console.log( "Modified:", modifiedArr );

Array.prototype.map() Ändern Sie das ursprüngliche Array

erreicht durch Neuzuweisung der Variable arr

var arr = ["1", 2, 3, 4];

arr = arr.map(function(v) {
  return "foo"+ v;
});

console.log( arr );

Array.prototype.forEach() Ändern Sie das ursprüngliche Array

erreicht durch Anzielen der Schlüssel nach Index arr[i]

var arr = ["1", 2, 3, 4];

arr.forEach(function(v, i) {
   arr[i] = "foo" + v;
});

console.log( "Original:", arr );

63
Roko C. Buljan

Javascript ist Wertübergabe und bedeutet im Wesentlichen, dass part eine Kopie des Werts im Array ist.

Um den Wert zu ändern, greifen Sie in Ihrer Schleife auf das Array selbst zu.

arr[index] = 'new value';

12
hvgotcodes

Die .forEach-Funktion kann eine Rückruffunktion haben (jedes Element, elementIndex) Grundsätzlich müssen Sie also Folgendes tun:

arr.forEach(function(element,index){
    arr[index] = "four";   //set the value  
});
console.log(arr); //the array has been overwritten.

Wenn Sie das ursprüngliche Array beibehalten möchten, können Sie eine Kopie davon erstellen, bevor Sie den obigen Vorgang ausführen. Um eine Kopie zu erstellen, können Sie Folgendes verwenden:

var copy = arr.slice();
2
zhujy_8833

ersetzen Sie es durch den Index des Arrays.

array[index] = new_value;
2
Asif Alamgir

Mit den Array-Objektmethoden können Sie den Array-Inhalt ändern, jedoch im Vergleich zu den grundlegenden for-Schleifen. Diesen Methoden fehlt eine wichtige Funktionalität. Sie können den Index für den Lauf nicht ändern.

Wenn Sie beispielsweise das aktuelle Element entfernen und es an einer anderen Indexposition innerhalb desselben Arrays platzieren, können Sie dies problemlos tun. Wenn Sie das aktuelle Element an eine vorherige Position verschieben, besteht kein Problem in der nächsten Iteration, und Sie erhalten dasselbe Element, als hätten Sie nichts getan.

Betrachten Sie diesen Code, bei dem wir das Element an Indexposition 5 an Indexposition 2 verschieben, sobald der Index bis 5 zählt.

var ar = [0,1,2,3,4,5,6,7,8,9];
ar.forEach((e,i,a) => {
i == 5 && a.splice(2,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 6 - 7 7 - 8 8 - 9 9

Wenn Sie jedoch das aktuelle Element an eine Stelle außerhalb der aktuellen Indexposition verschieben, wird dies etwas unordentlich. Das nächste Element wird dann in die Position der verschobenen Elemente verschoben, und in der nächsten Iteration können wir es nicht sehen oder bewerten.

Betrachten Sie diesen Code, bei dem wir das Element an Indexposition 5 an Indexposition 7 verschieben, sobald der Index bis 5 zählt.

var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && a.splice(7,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 7 - 7 5 - 8 8 - 9 9

Wir haben also noch nie 6 in der Schleife getroffen. Normalerweise wird in einer for-Schleife erwartet, dass Sie den Indexwert verringern, wenn Sie das Array-Element nach vorne verschieben, sodass der Index im nächsten Lauf an der gleichen Position bleibt und Sie das Element, das an die Stelle des entfernten Elements verschoben wurde, trotzdem auswerten kann. Dies ist bei Array-Methoden nicht möglich. Sie können den Index nicht ändern. Überprüfen Sie den folgenden Code

var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && (a.splice(7,0,a.splice(i,1)[0]), i--);
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 4 5 - 6 7 - 7 5 - 8 8 - 9 9

Wie Sie sehen, wenn wir i dekrementieren, wird es nicht von 5, sondern von 6 fortfahren.

Denken Sie also daran.

1
Redu

Hier eine ähnliche Antwort mit einer =>-Style-Funktion:

var data = [1,2,3,4];
data.forEach( (item, i, self) => self[i] = item + 10 );

gibt das Ergebnis:

[11,12,13,14]

Der Parameter self ist bei der Pfeilstil-Funktion nicht unbedingt erforderlich

data.forEach( (item,i) => data[i] = item + 10);

funktioniert auch. 

0
J. Peterson

Um Elemente vollständig hinzuzufügen oder zu löschen, die den Index ändern würden, durch Erweiterung von zhujy_8833, wobei slice () vorgeschlagen wird, eine Kopie zu durchlaufen, zählen Sie einfach die Anzahl der Elemente, die Sie bereits gelöscht oder hinzugefügt haben, und ändern Sie den Index entsprechend. So löschen Sie beispielsweise Elemente:

let values = ["A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"];
let count = 0;
values.slice().forEach((value, index) => {
    if (value === "A2" || value === "A5") {
        values.splice(index - count++, 1);
    };
});
console.log(values);

// Expected: [ 'A0', 'A1', 'A3', 'A4', 'A6', 'A7', 'A8' ]

Elemente einfügen vor:

if (value === "A0" || value === "A6" || value === "A8") {
    values.splice(index - count--, 0, 'newVal');
};

// Expected: ['newVal', A0, 'A1', 'A2', 'A3', 'A4', 'A5', 'newVal', 'A6', 'A7', 'newVal', 'A8' ]

Elemente einfügen nach:

if (value === "A0" || value === "A6" || value === "A8") {
    values.splice(index - --count, 0, 'newVal');
};

// Expected: ['A0', 'newVal', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'newVal', 'A7', 'A8', 'newVal']

So ersetzen Sie ein Element:

if (value === "A3" || value === "A4" || value === "A7") {
    values.splice(index, 1, 'newVal');
};

// Expected: [ 'A0', 'A1', 'A2', 'newVal', 'newVal', 'A5', 'A6', 'newVal', 'A8' ]

Hinweis: Wenn Sie sowohl 'Vorher' als auch 'Nach' Einfügungen implementieren, sollte der Code 'Vor' Einfügungen zuerst behandeln. Andernfalls wäre der umgekehrte Weg nicht wie erwartet

0
Leigh Mathieson