Ich arbeite am Odin-Projekt und an der Aufgabe "removeFromArray" von Fundamentals Part 4. Ich muss ein Array zurückgeben, das alle Elemente in der Liste der Argumente entfernt hat. Es funktioniert mit zwei Argumenten, aber ich kann es nicht mit vier Argumenten zum Laufen bringen. Mein Code ist unten:

const removeFromArray = function(firstArray, ...toRemove) {
    let modifiedArray = firstArray;

    for (i = 0; i < firstArray.length; i++) {
        if (modifiedArray.includes(toRemove[i])) {
            modifiedArray.splice(modifiedArray.indexOf(toRemove[i]), 1)
        }    
    }
    return modifiedArray;

}
removeFromArray([1, 2, 3, 4], 7, 2) // works, returns [1, 3, 4]
removeFromArray([1, 2, 3, 4], 3, 2) // also works, returns [1, 4]
removeFromArray([1, 2, 3, 4], 1, 2, 3, 4) //does not work, returns [3, 4]

Jede Hilfe wird sehr geschätzt.

0
Carl D'Oleo-Lundgren 24 Feb. 2020 im 00:02

6 Antworten

Beste Antwort

Ich denke, das eigentliche Problem hierbei ist, dass Sie möglicherweise nicht wissen, dass Arrays, Objekte und Funktionen in JavaScript als Referenz übergeben werden.

    let modifiedArray = firstArray;

Dies bedeutet, dass Ihr firstArray und das modifizierteArray beide auf dasselbe Array im Speicher verweisen. Der obige Code weist dem modifizierten Array genau das gleiche Array zu, technisch gesehen die Adresse im Speicher des ersten Arrays. Wenn Sie Elemente aus dem modifizierten Array entfernen, entfernen Sie sie daher auch aus dem ersten Array und ändern daher die Länge des ersten Arrays.

Sie müssen das Array nach Wert und nicht nach Referenz kopieren.

Lösung:

Daher ändern

let modifiedArray = firstArray;

Zu

let modifiedArray = [...firstArray];

Oder

let modifiedArray = firstArray.slice();

Die erste Lösung nutzt die Destrukturierung des ersten Arrays, um eine Kopie des Arrays nach Wert zu erstellen, ohne auf dasselbe Array im Speicher zu verweisen.

Die zweite ist Ihnen als Anfänger vielleicht vertrauter, da dies einfach eine Kopie des Arrays zurückgibt, ohne Elemente zu entfernen.

In diesem Thread finden Sie weitere Fragen zum Kopieren von Arrays nach Wert: Array nach Wert kopieren

const removeFromArray = function(firstArray, ...toRemove) {
    let modifiedArray = [...firstArray];

    for (i = 0; i < firstArray.length; i++) {
        if (modifiedArray.includes(toRemove[i])) {
            modifiedArray.splice(modifiedArray.indexOf(toRemove[i]), 1)
        }    
    }
    return modifiedArray;
}

console.log(removeFromArray([1, 2, 3, 4], 7, 2)); // works, returns [1, 3, 4]
console.log(removeFromArray([1, 2, 3, 4], 3, 2)); // also works, returns [1, 4]
console.log(removeFromArray([1, 2, 3, 4], 1, 2, 3, 4)); //does not work, returns [3, 4]
1
kevin 23 Feb. 2020 im 21:54
const removeFromArray = (firstArray, ...toRemove) => 
  firstArray.filter(e => !toRemove.includes(e));
      
console.log(removeFromArray([1, 2, 3, 4], 7, 2));
0
subarachnid 23 Feb. 2020 im 21:12

Sie verwenden denselben Index für das Array und für die zu entfernenden Elemente, die möglicherweise nicht identisch sind.


Sie können das Element iterieren, um es zu entfernen, den Index abzurufen und dieses Element aus firstArray zu verbinden.

Dieser Ansatz ändert das angegebene Array und behält dieselbe Objektreferenz bei.

const removeFromArray = function(firstArray, ...toRemove) {
    for (let i = 0; i < toRemove.length; i++) {
        let index = firstArray.indexOf(toRemove[i]);
        if (index === -1) continue;
        firstArray.splice(index, 1);
    }
    return firstArray;

}
console.log(...removeFromArray([1, 2, 3, 4], 7, 2));       // [1, 3, 4]
console.log(...removeFromArray([1, 2, 3, 4], 3, 2));       // [1, 4]
console.log(...removeFromArray([1, 2, 3, 4], 1, 2, 3, 4)); // []
0
Nina Scholz 23 Feb. 2020 im 21:08

Ich habe die folgende Zeile geändert:

let modifiedArray = firstArray;

Zu

let modifiedArray = [...firstArray];

Das Problem, mit dem Sie konfrontiert waren, war, dass Sie ein Array durchlaufen haben, vorausgesetzt, es ist eine Kopie des ersten Arrays. Aber es zeigte nur auf firstArray. Jetzt haben Sie in der Schleife begonnen, Elemente aus dem Array zu entfernen, und nachdem Sie 2 in der Iteration entfernt hatten, befanden Sie sich bereits in 2, sodass nichts mehr zu wiederholen war ...

const removeFromArray = function(firstArray, ...toRemove) {
    let modifiedArray = [...firstArray];
    for (var i = 0; i < firstArray.length; i++) {
        if (modifiedArray.includes(toRemove[i])) {
            modifiedArray.splice(modifiedArray.indexOf(toRemove[i]), 1)
        }    
    }
    return modifiedArray;

}
var x = removeFromArray([1, 2, 3, 4], 7, 2);
var y = removeFromArray([1, 2, 3, 4], 3, 2);
var z = removeFromArray([1, 2, 3, 4], 1, 2, 3, 4);

console.log('x', x);
console.log('y', y);
console.log('z', z);
1
caramba 23 Feb. 2020 im 21:12
 1, 2, 3, 4

Nachdem Sie das erste Element entfernt haben, wird alles nach unten verschoben, sodass das zweite Element zum ersten Element wird.

Sie haben dieses Problem nicht, wenn Sie am Ende beginnen und umgekehrt arbeiten (sortieren Sie die Liste der zu entfernenden Elemente).

1
Quentin 23 Feb. 2020 im 21:05

Durch das Spleißen aus dem Array werden alle verbleibenden Elemente um eins nach unten verschoben, sodass Sie am Ende das nächste Element überspringen. Ich würde empfehlen, Array.prototype.filter zu verwenden stattdessen.

2
snek 23 Feb. 2020 im 21:05