Wie kann ich ein bestimmtes Element aus einem Array entfernen?

8293

Ich habe ein Array von Zahlen und verwende die .push()Methode, um Elemente hinzuzufügen.

Gibt es eine einfache Möglichkeit, ein bestimmtes Element aus einem Array zu entfernen?

Ich suche das Äquivalent von etwas wie:

array.remove(number);

Ich muss Kern- JavaScript verwenden. Frameworks sind nicht erlaubt.

Gehhilfe
quelle

Antworten:

11890

Suchen Sie das indexArray-Element, das Sie mit entfernen möchten indexOf, und entfernen Sie dann diesen Index mit splice.

Die splice () -Methode ändert den Inhalt eines Arrays, indem vorhandene Elemente entfernt und / oder neue Elemente hinzugefügt werden.

const array = [2, 5, 9];

console.log(array);

const index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}

// array = [2, 9]
console.log(array); 

Der zweite Parameter von spliceist die Anzahl der zu entfernenden Elemente. Beachten Sie, dass splicedas vorhandene Array geändert wird und ein neues Array zurückgegeben wird, das die entfernten Elemente enthält.


Der Vollständigkeit halber sind hier Funktionen aufgeführt. Die erste Funktion entfernt nur ein einzelnes Vorkommen (dh das Entfernen der ersten Übereinstimmung von 5von [2,5,9,1,5,8,5]), während die zweite Funktion alle Vorkommen entfernt:

function removeItemOnce(arr, value) { 
    var index = arr.indexOf(value);
    if (index > -1) {
        arr.splice(index, 1);
    }
    return arr;
}

function removeItemAll(arr, value) {
    var i = 0;
    while (i < arr.length) {
        if(arr[i] === value) {
            arr.splice(i, 1);
        } else {
            ++i;
        }
    }
    return arr;
}
Tom Wadley
quelle
15
@ Peter, ja du könntest recht haben. Dieser Artikel erklärt mehr und hat eine Problemumgehung für inkompatible Browser: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Tom Wadley
33
@AlexandreWiechersVaz Natürlich bewahrt es Ordnung, wenn es nicht wäre, wäre es absolut wertlos
TheZ
15
Sie können das Problem mit der Unterstützung des IE-Browsers lösen, indem Sie den hier angegebenen
15
@AdrianP. array.indexOf(testValue)auf leerem Array ist -1, und wenn Sie darauf testen, dann kein Spleiß. Vielleicht hat sich die Antwort seitdem geändert.
UpTheCreek
13
IE 7, IE8, IE9, IE10 werden von Microsoft selbst nicht unterstützt. Warum sollten Webentwickler diese alten Browser unterstützen? Zeigen Sie einfach eine Benachrichtigung über das Upgrade des Browsers an! support.microsoft.com/en-us/lifecycle/…
Lukas Liesis
1266

Ich weiß nicht, wie Sie sich array.remove(int)verhalten sollen. Ich kann mir drei Möglichkeiten vorstellen, die Sie sich wünschen könnten.

So entfernen Sie ein Element eines Arrays an einem Index i:

array.splice(i, 1);

Wenn Sie jedes Element mit Wert numberaus dem Array entfernen möchten :

for(var i = array.length - 1; i >= 0; i--) {
    if(array[i] === number) {
        array.splice(i, 1);
    }
}

Wenn Sie nur möchten, dass das Element am Index inicht mehr vorhanden ist, die Indizes der anderen Elemente jedoch nicht geändert werden sollen:

delete array[i];
Peter Olson
quelle
334
deleteist nicht der richtige Weg, um ein Element aus einem Array zu entfernen!
Felix Kling
71
@FelixKling Es hängt davon ab, ob es funktioniert, wenn Sie es so machen möchten, dass es array.hasOwnProperty(i)zurückkehrt falseund das Element an dieser Position zurückgibt undefined. Aber ich gebe zu, dass das nicht sehr häufig ist.
Peter Olson
88
deleteaktualisiert weder die Länge des Arrays noch löscht es das Element wirklich, sondern ersetzt es nur durch den speziellen Wert undefined.
Diosney
34
@diosney Ich weiß nicht, was du meinst, wenn du sagst, dass es das Element nicht wirklich löscht. Ferner ist es mehr kann , als nur mit dem Wert an diesem Index zu ersetzen undefined: Es entfernt sowohl den Index und den Wert aus dem Feld, nachdem das heißt delete array[0], "0" in arraywird falsch zurück.
Peter Olson
17
@GrantGryczan Entschuldigung, ich bin anderer Meinung. Ich sehe keine Notwendigkeit, dies zu entfernen. Der obige Text erklärt klar, was er tut, und hilft Menschen, die nicht wissen, was er deletetut, zu verstehen, warum er nicht wie erwartet funktioniert.
Peter Olson
1204

Bearbeitet am Oktober 2016

  • Mach es einfach, intuitiv und explizit ( Occams Rasiermesser )
  • Mach es unveränderlich (ursprüngliches Array bleibt unverändert)
  • Tun Sie dies mit Standard-JavaScript-Funktionen, wenn Ihr Browser diese nicht unterstützt - verwenden Sie Polyfill

In diesem Codebeispiel verwende ich die Funktion "array.filter (...)" , um unerwünschte Elemente aus einem Array zu entfernen. Diese Funktion ändert das ursprüngliche Array nicht und erstellt ein neues. Wenn Ihr Browser diese Funktion nicht unterstützt (z. B. Internet Explorer vor Version 9 oder Firefox vor Version 1.5), sollten Sie die Filter-Polyfüllung von Mozilla verwenden .

Element entfernen (ECMA-262 Edition 5-Code, auch bekannt als Oldstyle-JavaScript)

var value = 3

var arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(function(item) {
    return item !== value
})

console.log(arr)
// [ 1, 2, 4, 5 ]

Element entfernen (ECMAScript 6-Code)

let value = 3

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => item !== value)

console.log(arr)
// [ 1, 2, 4, 5 ]

WICHTIG Die Pfeilfunktionssyntax von ECMAScript 6 "() => {}" wird in Internet Explorer überhaupt nicht unterstützt, Chrome vor Version 45, Firefox vor Version 22 und Safari vor Version 10. Um die ECMAScript 6-Syntax in alten Browsern zu verwenden, können Sie BabelJS verwenden .


Mehrere Elemente entfernen (ECMAScript 7-Code)

Ein zusätzlicher Vorteil dieser Methode besteht darin, dass Sie mehrere Elemente entfernen können

let forDeletion = [2, 3, 5]

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => !forDeletion.includes(item))
// !!! Read below about array.includes(...) support !!!

console.log(arr)
// [ 1, 4 ]

WICHTIG Die Funktion "array.includes (...)" wird in Internet Explorer überhaupt nicht unterstützt, Chrome vor Version 47, Firefox vor Version 43, Safari vor Version 9 und Edge vor Version 14. Hier ist also Polyfill von Mozilla .

Entfernen mehrerer Elemente (möglicherweise in Zukunft)

Wenn der Vorschlag "Diese verbindliche Syntax" jemals akzeptiert wird, können Sie Folgendes tun:

// array-lib.js

export function remove(...forDeletion) {
    return this.filter(item => !forDeletion.includes(item))
}

// main.js

import { remove } from './array-lib.js'

let arr = [1, 2, 3, 4, 5, 3]

// :: This-Binding Syntax Proposal
// using "remove" function as "virtual method"
// without extending Array.prototype
arr = arr::remove(2, 3, 5)

console.log(arr)
// [ 1, 4 ]

Probieren Sie es selbst in BabelJS :)

Referenz

ujeenator
quelle
6
Aber manchmal möchten wir ein Element aus dem ursprünglichen Array entfernen (nicht unveränderlich), zum Beispiel ein Array, das in der Angular 2 * ngFor-Direktive
Ravinder Payal vom
43
Besser als die akzeptierte Lösung, da nicht nur ein Spiel auftritt und Unveränderlichkeit vorzuziehen ist
Greg
13
filtermuss für ein großes Array allerdings viel langsamer sein?
Nathan
3
Was ist der Punkt der Unveränderlichkeit, der erwähnt wird, wenn Sie in Ihren Beispielen die Zuweisung derselben Variablen verwendet haben? :)
Mench
12
Dies ist eine großartige Antwort. Splice ist eine spezielle Funktion zum Mutieren und nicht zum Filtern. filterMöglicherweise ist die Leistung langsamer, aber der Code ist sicherer und besser. Sie können auch nach Index filtern, indem Sie ein zweites Argument im Lambda angeben:arr.filter((x,i)=>i!==2)
Matthew
449

Es hängt davon ab, ob Sie einen leeren Platz behalten möchten oder nicht.

Wenn Sie einen leeren Steckplatz möchten, ist Löschen in Ordnung:

delete array[index];

Wenn Sie dies nicht tun, sollten Sie die Spleißmethode verwenden:

array.splice(index, 1);

Und wenn Sie den Wert dieses Elements benötigen, können Sie einfach das Element des zurückgegebenen Arrays speichern:

var value = array.splice(index, 1)[0];

Falls Sie dies in einer bestimmten Reihenfolge tun möchten, können Sie es array.pop()für die letzte oder array.shift()für die erste verwenden (und beide geben auch den Wert des Elements zurück).

Und wenn Sie den Index des Artikels nicht kennen, können Sie ihn verwenden array.indexOf(item), um ihn zu erhalten (in a if(), um einen Artikel zu erhalten, oder in a while(), um alle zu erhalten). array.indexOf(item)Gibt entweder den Index oder -1 zurück, wenn er nicht gefunden wird. 

xavierm02
quelle
25
deleteist nicht der richtige Weg, um ein Element aus einem Array zu entfernen !!
Progo
16
Wenn Sie "einen Steckplatz leeren" möchten, verwenden Sie array[index] = undefined;. Die Verwendung deletezerstört die Optimierung.
Bergi
4
@ Jakub sehr guter Kommentar, weil zu verstehen, dass ich viel Zeit verloren habe und dachte, mein Anwendungscode ist irgendwie kaputt ...
Pascal
Der letzte Absatz mit der Erklärung, was Sie von indexOf erhalten, war wirklich hilfreich
A. D'Alfonso
277

Ein Freund hatte Probleme mit Internet Explorer 8 und zeigte mir, was er tat. Ich sagte ihm, dass es falsch sei, und er sagte mir, dass er hier die Antwort bekommen habe. Die aktuelle Top-Antwort funktioniert nicht in allen Browsern (z. B. Internet Explorer 8) und entfernt nur das erste Vorkommen des Elements.

Entfernen Sie ALLE Instanzen aus einem Array

function remove(arr, item) {
    for (var i = arr.length; i--;) {
        if (arr[i] === item) {
            arr.splice(i, 1);
        }
    }
}

Es durchläuft das Array rückwärts (da sich Indizes und Länge ändern, wenn Elemente entfernt werden) und entfernt das Element, wenn es gefunden wird. Es funktioniert in allen Browsern.

Ben Lesh
quelle
11
@sroes sollte es nicht sein, weil die Schleife am i = arr.length -1oder i--mit dem maximalen Index beginnt . arr.lengthist nur ein Anfangswert für i. i--wird immer wahr sein (und bei jeder Schleifenoperation um 1 reduzieren), bis es gleich ist 0(ein falscher Wert) und die Schleife dann stoppt.
Gmajivu
1
Die zweite Funktion ist ziemlich ineffizient. Bei jeder Iteration startet "indexOf" die Suche am Anfang des Arrays.
Ujeenator
3
@AmberdeBlack, auf einer Sammlung mit mehr als 1 Vorkommen von Elemente , es ist viel besser , das nennen Filter anstelle Methode arr.filter(function (el) { return el !== item }), die Notwendigkeit vermieden wird, die Anordnung mehrfach zu mutieren. Dies verbraucht etwas mehr Speicher, arbeitet aber viel effizienter, da weniger Arbeit erledigt werden muss.
Eugene Kuzmenko
1
@AlJey, es ist nur ab IE9 + verfügbar. Es besteht immer noch die Möglichkeit, dass es nicht funktioniert.
Ujeenator
1
Diese Antwort hat bei mir funktioniert, da mehrere Elemente entfernt werden mussten, jedoch nicht in einer bestimmten Reihenfolge. Der Rückwärtsverlauf der for-Schleife behandelt hier das Entfernen von Elementen aus dem Array perfekt.
Mintedsky
172

Es gibt zwei Hauptansätze:

  1. Spleiß () :anArray.splice(index, 1);

  2. löschen :delete anArray[index];

Seien Sie vorsichtig, wenn Sie delete für ein Array verwenden. Es ist gut zum Löschen von Attributen von Objekten, aber nicht so gut für Arrays. Es ist besser, splicefür Arrays zu verwenden.

Denken Sie daran, wenn Sie verwenden delete für ein Array möglicherweise falsche Ergebnisse erzielt werden anArray.length. Mit anderen Worten, deletewürde das Element entfernen, aber den Wert der Eigenschaft length nicht aktualisieren.

Sie können auch erwarten, dass nach der Verwendung von delete Lücken in den Indexnummern vorhanden sind, z. B. könnten Sie die Indizes 1, 3, 4, 8, 9 und 11 und die Länge wie vor der Verwendung von delete haben. In diesem Fall sind alle indiziertfor Schleifen abstürzen, da die Indizes nicht mehr sequentiell sind.

Wenn Sie deleteaus irgendeinem Grund zur Verwendung gezwungen sind , sollten Sie for eachSchleifen verwenden, wenn Sie Arrays durchlaufen müssen. Vermeiden Sie nach forMöglichkeit immer die Verwendung von indizierten Schleifen. Auf diese Weise wäre der Code robuster und weniger anfällig für Probleme mit Indizes.

Sasa
quelle
144
Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}
//Call like
[1, 2, 3, 4].remByVal(3);

Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}

var rooms = ['hello', 'something']

rooms = rooms.remByVal('hello')

console.log(rooms)

Zirak
quelle
14
Ich bin kein großer Fan dieses Ansatzes. Wenn Sie unterschiedliche Bibliotheken oder Frameworks verwenden, kann dies zu Konflikten führen.
Charlie Kilian
10
Schlechte Idee, siehe diesen Beitrag: stackoverflow.com/questions/948358/array-prototype-problem
MMeah
10
Wenn Sie for inein Array ausführen, haben Sie bereits ein Problem.
Zirak
2
Wenn Sie for inauf Arrays arbeiten, haben Sie bereits größere Probleme.
Rainb
Verwenden Sie Object.defineProperty stackoverflow.com/a/35518127/3779853 und los geht's.
Phil294
105

Es besteht keine Notwendigkeit, indexOfoder zu verwenden splice. Es funktioniert jedoch besser, wenn Sie nur ein Vorkommen eines Elements entfernen möchten.

Finden und bewegen (bewegen):

function move(arr, val) {
  var j = 0;
  for (var i = 0, l = arr.length; i < l; i++) {
    if (arr[i] !== val) {
      arr[j++] = arr[i];
    }
  }
  arr.length = j;
}

Verwendung indexOfund splice(indexof):

function indexof(arr, val) {
  var i;
  while ((i = arr.indexOf(val)) != -1) {
    arr.splice(i, 1);
  }
}

Nur verwenden splice(Spleiß):

function splice(arr, val) {
  for (var i = arr.length; i--;) {
    if (arr[i] === val) {
      arr.splice(i, 1);
    }
  }
}

Laufzeiten auf NodeJS für ein Array mit 1000 Elementen (durchschnittlich über 10000 Läufe):

indexof ist ungefähr 10x langsamer als move . Selbst wenn es durch Entfernen des Aufrufs von indexOfin splice verbessert wird, ist die Leistung viel schlechter als das Verschieben .

Remove all occurrences:
    move 0.0048 ms
    indexof 0.0463 ms
    splice 0.0359 ms

Remove first occurrence:
    move_one 0.0041 ms
    indexof_one 0.0021 ms
slosd
quelle
5
Die hier vorgestellte "Verschieben" -Methode sollte in allen Browsern funktionieren und das Erstellen eines zusätzlichen Arrays vermeiden. Die meisten anderen Lösungen hier haben eines oder beide dieser Probleme. Ich denke, dieser verdient viel mehr Stimmen, auch wenn er nicht so "hübsch" aussieht.
Sockmonk
73

Dies liefert ein Prädikat anstelle eines Wertes.

HINWEIS: Das angegebene Array wird aktualisiert und die betroffenen Zeilen werden zurückgegeben.

Verwendungszweck

var removed = helper.removeOne(arr, row => row.id === 5 );

var removed = helper.remove(arr, row => row.name.startsWith('BMW'));

Definition

var helper = {

    // Remove and return the first occurrence

    removeOne: function(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                return array.splice(i, 1);
            }
        }
    },

    // Remove and return all occurrences

    remove: function(array, predicate) {
        var removed = [];

        for (var i = 0; i < array.length;) {

            if (predicate(array[i])) {
                removed.push(array.splice(i, 1));
                continue;
            }
            i++;
        }
        return removed;
    }
};
amd
quelle
Ich weiß nicht, dass Sie den -1-Check benötigen (i> -1). Ich denke auch, dass diese Funktionen eher wie Filter als wie Entfernen wirken. Wenn Sie row.id === 5 übergeben, wird ein Array mit nur ID 5 erstellt, sodass das Gegenteil von remove geschieht. In ES2015 würde es gut aussehen: var result = ArrayHelper.remove (myArray, row => row.id === 5);
Was wäre cool
@WhatWouldBeCool Diese Funktion ändert das ursprüngliche Array und gibt das entfernte Element zurück, anstatt das Ergebnis in ein neues Array zu kopieren
amd
68

Sie können dies einfach mit der Filtermethode tun :

function remove(arrOriginal, elementToRemove){
    return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log(remove([1, 2, 1, 0, 3, 1, 4], 1));

Dies entfernt alle Elemente aus dem Array und arbeitet auch schneller als eine Kombination von sliceund indexOf.

Salvador Dali
quelle
3
Haben Sie eine Quelle dafür, dass dies schneller ist?
user3711421
2
Schöne Lösung. Aber wie Sie betonen, aber wichtig, um eine Glatze zu machen, erzeugt es nicht das gleiche Ergebnis wie Slice und IndexOf, da es alle Vorkommen von 1
user3711421
1
@ user3711421 Dies liegt daran, dass nur Slice und IndexOf nicht das tun, was er will, "um ein bestimmtes Element zu entfernen". Es entfernt das Element nur einmal, dies entfernt ein bestimmtes Element, egal wie viele von ihnen Sie haben
Salvador Dali
66

John Resig hat eine gute Implementierung gepostet :

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

Wenn Sie ein globales Objekt nicht erweitern möchten, können Sie stattdessen Folgendes tun:

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

Der Hauptgrund, warum ich dies veröffentliche, besteht darin, Benutzer vor der alternativen Implementierung zu warnen, die in den Kommentaren auf dieser Seite (14. Dezember 2007) vorgeschlagen wurde:

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

Zunächst scheint es gut zu funktionieren, aber durch einen schmerzhaften Prozess habe ich festgestellt, dass es fehlschlägt, wenn versucht wird, das vorletzte Element in einem Array zu entfernen. Wenn Sie beispielsweise ein Array mit 10 Elementen haben und versuchen, das 9. Element damit zu entfernen:

myArray.remove(8);

Sie erhalten ein Array mit 8 Elementen. Ich weiß nicht warum, aber ich habe bestätigt, dass Johns ursprüngliche Implementierung dieses Problem nicht hat.

Roger
quelle
Gerade auf die harte Object.prototype.hasOwnPropertyTour gelernt, warum es eine gute Idee ist, immer ¬¬ zu verwenden
Davi Fiamenghi
64

Mit Underscore.js können Probleme mit mehreren Browsern gelöst werden. Falls vorhanden, werden eingebaute Browsermethoden verwendet. Wenn sie nicht vorhanden sind, wie bei älteren Internet Explorer-Versionen, werden eigene benutzerdefinierte Methoden verwendet.

Ein einfaches Beispiel zum Entfernen von Elementen aus dem Array (von der Website):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]
vatsal
quelle
Obwohl elegant und prägnant, erwähnte OP klar nur den Kern JS
EigenFool
64

Sie können ES6 verwenden. Zum Beispiel, um den Wert '3' in diesem Fall zu löschen:

var array=['1','2','3','4','5','6']
var newArray = array.filter((value)=>value!='3');
console.log(newArray);

Ausgabe :

["1", "2", "4", "5", "6"]
rajat44
quelle
4
Diese Antwort ist hilfreich, da eine Kopie des ursprünglichen Arrays erstellt wird, anstatt das Original direkt zu ändern.
Claudio Holanda
Hinweis: Array.prototype.filter ist ECMAScript 5.1 (kein IE8). Für spezifischere Lösungen: stackoverflow.com/a/54390552/8958729
Chang
54

Wenn Sie ein neues Array mit entfernten gelöschten Positionen wünschen, können Sie jederzeit das bestimmte Element löschen und das Array herausfiltern. Für Browser, die die Filtermethode nicht implementieren, ist möglicherweise eine Erweiterung des Array-Objekts erforderlich. Auf lange Sicht ist dies jedoch einfacher, da Sie lediglich Folgendes tun:

var my_array = [1, 2, 3, 4, 5, 6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));

Es sollte angezeigt werden [1, 2, 3, 4, 6].

Loupax
quelle
45

Überprüfen Sie diesen Code. Es funktioniert in jedem gängigen Browser .

remove_item = function (arr, value) {
    var b = '';
    for (b in arr) {
        if (arr[b] === value) {
            arr.splice(b, 1);
            break;
        }
    }
    return arr;
}

Rufen Sie diese Funktion auf

remove_item(array,value);
Ekramul Hoque
quelle
4
@RolandIllig Außer der Verwendung einer for in-loop und der Tatsache, dass das Skript früher gestoppt werden konnte, indem das Ergebnis direkt aus der Schleife zurückgegeben wurde. Die Upvotes sind angemessen;)
Yckart
1
Dies ist ein ausgezeichneter Ansatz für kleine Arrays. Es funktioniert in jedem Browser, verwendet minimalen und intuitiven Code und ohne besonders komplexe Frameworks, Shims oder Polyfills.
Beejor
Ich sollte auch den Kommentar von yckart wiederholen, for( i = 0; i < arr.length; i++ )der ein besserer Ansatz wäre, da er die genauen Indizes gegenüber der Reihenfolge beibehält, in der der Browser die Elemente (mit for in) speichert . Auf diese Weise können Sie auch den Array-Index eines Werts abrufen, wenn Sie ihn benötigen.
Beejor
41

Sie können lodash _.pull (mutiertes Array), _.pullAt (mutiertes Array) oder _.without (mutiertes Array nicht) verwenden.

var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']

var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']

var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']
Chun Yang
quelle
2
Das ist nicht das Kern-JS, wie es das OP verlangt hat, oder?
einige-nicht-beschreibende-Benutzer
12
@ some-non-description-user Du hast recht. Aber viele Benutzer wie ich kommen hierher und suchen nach einer allgemeinen Antwort, nicht nur für das OP.
Chun Yang
@ChunYang Du hast absolut recht. Ich benutze bereits lodash, warum nicht einfach, wenn es Zeit spart.
Int-I
38

ES6 & ohne Mutation: (Oktober 2016)

const removeByIndex = (list, index) =>
      [
        ...list.slice(0, index),
        ...list.slice(index + 1)
      ];
         
output = removeByIndex([33,22,11,44],1) //=> [33,11,44]
      
console.log(output)

Abdennour TOUMI
quelle
Warum nicht einfach filterdann verwenden? array.filter((_, index) => index !== removedIndex);.
user4642212
@ user4642212 du hast recht! Ich mochte auch den Unterstrich des Golang-Stils
Abdennour TOUMI
36

Das Entfernen eines bestimmten Elements / Strings aus einem Array kann in einem Einzeiler erfolgen:

theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);

wo:

theArray : Das Array, aus dem Sie etwas Bestimmtes entfernen möchten

stringToRemoveFromArray : Die Zeichenfolge, die entfernt werden soll, und 1 ist die Anzahl der Elemente, die Sie entfernen möchten.

HINWEIS : Wenn sich "stringToRemoveFromArray" nicht in Ihrem Array befindet, wird das letzte Element des Arrays entfernt.

Es ist immer empfehlenswert, zuerst zu überprüfen, ob das Element in Ihrem Array vorhanden ist, bevor Sie es entfernen.

if (theArray.indexOf("stringToRemoveFromArray") >= 0){
   theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);
}

Wenn Sie auf den Computern Ihres Clients Zugriff auf neuere Ecmascript-Versionen haben (WARNUNG, funktioniert möglicherweise nicht auf älteren Stationen):

var array=['1','2','3','4','5','6']
var newArray = array.filter((value)=>value!='3');

Wobei '3' der Wert ist, den Sie aus dem Array entfernen möchten. Das Array würde dann werden:['1','2','4','5','6']

Max Alexander Hanna
quelle
Dies ist die Antwort, die für mich funktioniert hat, als ich versucht habe, ein Array basierend auf dem Umschalten von Optionsfeldern zu aktualisieren.
jdavid05
4
Beachten Sie, dass "stringToRemoveFromArray"das letzte Element des Arrays entfernt wird , wenn es sich nicht in Ihrem Array befindet.
Fusion
35

Hier sind einige Möglichkeiten, um ein Element mithilfe von JavaScript aus einem Array zu entfernen .

Alle beschriebenen Methoden mutieren nicht das ursprüngliche Array , sondern erstellen stattdessen ein neues.

Wenn Sie den Index eines Elements kennen

Angenommen, Sie haben ein Array und möchten ein Element an seiner Position entfernen i .

Eine Methode ist zu verwenden slice():

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const i = 3
const filteredItems = items.slice(0, i).concat(items.slice(i+1, items.length))

console.log(filteredItems)

slice()Erstellt ein neues Array mit den empfangenen Indizes. Wir erstellen einfach ein neues Array vom Anfang bis zum Index, den wir entfernen möchten, und verketten ein anderes Array von der ersten Position nach der Position, die wir entfernt haben, bis zum Ende des Arrays.

Wenn Sie den Wert kennen

In diesem Fall ist die Verwendung eine gute Option filter(), die einen deklarativeren Ansatz bietet :

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)

console.log(filteredItems)

Dies verwendet die ES6-Pfeilfunktionen. Sie können die herkömmlichen Funktionen verwenden, um ältere Browser zu unterstützen:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(function(item) {
  return item !== valueToRemove
})

console.log(filteredItems)

Oder Sie können Babel verwenden und den ES6-Code zurück in ES5 transpilieren, um ihn für alte Browser besser verdaulich zu machen, und dennoch modernes JavaScript in Ihren Code schreiben.

Mehrere Elemente entfernen

Was ist, wenn Sie anstelle eines einzelnen Elements viele Elemente entfernen möchten?

Lassen Sie uns die einfachste Lösung finden.

Nach Index

Sie können einfach eine Funktion erstellen und Elemente in Serie entfernen:

const items = ['a', 'b', 'c', 'd', 'e', 'f']

const removeItem = (items, i) =>
  items.slice(0, i-1).concat(items.slice(i, items.length))

let filteredItems = removeItem(items, 3)
filteredItems = removeItem(filteredItems, 5)
//["a", "b", "c", "d"]

console.log(filteredItems)

Nach Wert

Sie können nach der Aufnahme in die Rückruffunktion suchen:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]

console.log(filteredItems)

Vermeiden Sie die Mutation des ursprünglichen Arrays

splice()(nicht zu verwechseln mit slice()) mutiert das ursprüngliche Array und sollte vermieden werden.

(ursprünglich veröffentlicht unter https://flaviocopes.com/how-to-remove-item-from-array/ )

Flavio Copes
quelle
34

OK, zum Beispiel haben Sie das folgende Array:

var num = [1, 2, 3, 4, 5];

Und wir möchten Nummer 4 löschen. Sie können einfach den folgenden Code verwenden:

num.splice(num.indexOf(4), 1); // num will be [1, 2, 3, 5];

Wenn Sie diese Funktion wiederverwenden, schreiben Sie eine wiederverwendbare Funktion, die wie folgt an die native Array-Funktion angehängt wird:

Array.prototype.remove = Array.prototype.remove || function(x) {
  const i = this.indexOf(x);
  if(i===-1)
      return;
  this.splice(i, 1); // num.remove(5) === [1, 2, 3];
}

Aber wie wäre es, wenn Sie stattdessen das folgende Array mit ein paar [5] s im Array haben?

var num = [5, 6, 5, 4, 5, 1, 5];

Wir brauchen eine Schleife, um sie alle zu überprüfen, aber eine einfachere und effizientere Möglichkeit ist die Verwendung integrierter JavaScript-Funktionen. Deshalb schreiben wir eine Funktion, die stattdessen einen Filter wie den folgenden verwendet:

const _removeValue = (arr, x) => arr.filter(n => n!==x);
//_removeValue([1, 2, 3, 4, 5, 5, 6, 5], 5) // Return [1, 2, 3, 4, 6]

Es gibt auch Bibliotheken von Drittanbietern, die Ihnen dabei helfen, wie Lodash oder Underscore. Weitere Informationen finden Sie unter lodash _.pull, _.pullAt oder _.without.

Alireza
quelle
Es gibt einen kleinen Tippfehler. Bitte korrigieren. this.splice(num.indexOf(x), 1);=>this.splice(this.indexOf(x), 1);
TheGwa
Bitte erweitern Sie die integrierten Funktionen (Funktionen an Array.prototype anhängen) in JavaScript nicht. Dies wird allgemein als schlechte Praxis angesehen.
Aikeru
Ich bin damit einverstanden, dass dies nicht das Beste auf der Welt ist, aber wie können Sie es in diesem Fall an die Funktion weitergeben?
Alireza
Sie sollten den Index überprüfen. Wenn index = -1, wird Spleiß (-1,1) das letzte Element entfernen
Richard Chan
29

Ich bin ziemlich neu in JavaScript und brauchte diese Funktionalität. Ich habe nur folgendes geschrieben:

function removeFromArray(array, item, index) {
  while((index = array.indexOf(item)) > -1) {
    array.splice(index, 1);
  }
}

Dann, wenn ich es benutzen möchte:

//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];

//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");

Ausgabe - Wie erwartet. ["item1", "item1"]

Möglicherweise haben Sie andere Anforderungen als ich, sodass Sie sie problemlos an sie anpassen können. Ich hoffe das hilft jemandem.

Sofiax
quelle
1
Dies wird ein schreckliches Verhalten haben, wenn Ihr Array wirklich lang ist und mehrere Instanzen des Elements darin enthalten sind. Die indexOf-Methode des Arrays beginnt jedes Mal am Anfang, sodass Ihre Kosten O (n ^ 2) betragen.
Zag
@ Zag: Es hat einen Namen: Shlemiel der Algorithmus des Malers
Peter Mortensen
27

Wenn Sie komplexe Objekte im Array haben, können Sie Filter verwenden? In Situationen, in denen $ .inArray oder array.splice nicht so einfach zu verwenden sind. Besonders wenn die Objekte im Array vielleicht flach sind.

Beispiel: Wenn Sie ein Objekt mit einem ID-Feld haben und möchten, dass das Objekt aus einem Array entfernt wird:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});
mürrisch
quelle
So mache ich es gerne. Mit einer Pfeilfunktion kann es sich um einen Einzeiler handeln. Ich bin neugierig auf Leistung. Auch nichts wert , dass diese ersetzt das Array. Code mit einem Verweis auf das alte Array bemerkt die Änderung nicht.
Joeytwiddle
27

Ich möchte basierend auf ECMAScript 6 antworten . Angenommen, Sie haben ein Array wie das folgende:

let arr = [1,2,3,4];

Wenn Sie an einem speziellen Index wie löschen möchten 2, schreiben Sie den folgenden Code:

arr.splice(2, 1); //=> arr became [1,2,4]

Wenn Sie jedoch ein spezielles Element wie löschen möchten 3und dessen Index Sie nicht kennen, gehen Sie wie folgt vor:

arr = arr.filter(e => e !== 3); //=> arr became [1,2,4]

Hinweis : Bitte verwenden Sie eine Pfeilfunktion für den Filterrückruf, es sei denn, Sie erhalten ein leeres Array.

AmerllicA
quelle
25

Update: Diese Methode wird nur empfohlen, wenn Sie ECMAScript 2015 (früher bekannt als ES6) nicht verwenden können. Wenn Sie es verwenden können, bieten andere Antworten hier viel übersichtlichere Implementierungen.


Dieser Kern hier löst Ihr Problem und löscht auch alle Vorkommen des Arguments anstelle von nur 1 (oder einem angegebenen Wert).

Array.prototype.destroy = function(obj){
    // Return null if no objects were found and removed
    var destroyed = null;

    for(var i = 0; i < this.length; i++){

        // Use while-loop to find adjacent equal objects
        while(this[i] === obj){

            // Remove this[i] and store it within destroyed
            destroyed = this.splice(i, 1)[0];
        }
    }

    return destroyed;
}

Verwendungszweck:

var x = [1, 2, 3, 3, true, false, undefined, false];

x.destroy(3);         // => 3
x.destroy(false);     // => false
x;                    // => [1, 2, true, undefined]

x.destroy(true);      // => true
x.destroy(undefined); // => undefined
x;                    // => [1, 2]

x.destroy(3);         // => null
x;                    // => [1, 2]
zykadelic
quelle
25

Performance

Heute (09.12.2019) führe ich Leistungstests unter macOS 10.13.6 (High Sierra) für ausgewählte Lösungen durch. ich zeigedelete (A), aber ich benutze es nicht im Vergleich zu anderen Methoden, weil es leeren Raum im Array gelassen hat.

Die Schlussfolgerungen

  • Die schnellste Lösung ist array.splice(C) (außer Safari für kleine Arrays, bei denen es das zweite Mal gibt).
  • Für große Arrays ist array.slice+splice(H) die schnellste unveränderliche Lösung für Firefox und Safari. Array.from(B) ist in Chrome am schnellsten
  • veränderbare Lösungen sind normalerweise 1,5x-6x schneller als unveränderlich
  • Bei kleinen Tabellen auf Safari ist die veränderliche Lösung (C) überraschenderweise langsamer als die unveränderliche Lösung (G).

Einzelheiten

In Tests entferne ich das mittlere Element auf verschiedene Weise aus dem Array. Die A, C- Lösungen sind vorhanden. Die Lösungen B, D, E, F, G, H sind unveränderlich.

Ergebnisse für Array mit 10 Elementen

Geben Sie hier die Bildbeschreibung ein

In Chrome ist array.splice(C) die schnellste In-Place-Lösung. Das array.filter(D) ist die schnellste unveränderliche Lösung. Das langsamste ist array.slice(F). Sie können den Test auf Ihrem Rechner ausführen hier .

Ergebnisse für Array mit 1.000.000 Elementen

Geben Sie hier die Bildbeschreibung ein

In Chrome ist array.splice(C) die schnellste In-Place-Lösung ( delete(C) ist ähnlich schnell - es wurde jedoch ein leerer Steckplatz im Array belassen (sodass keine vollständige Entfernung durchgeführt wird)). Das array.slice-splice(H) ist die schnellste unveränderliche Lösung. Das langsamste ist array.filter(D und E). Sie können den Test auf Ihrem Rechner ausführen hier .

Vergleich für Browser: Chrome v78.0.0, Safari v13.0.4 und Firefox v71.0.0

Geben Sie hier die Bildbeschreibung ein

Kamil Kiełczewski
quelle
24

Sie sollten Ihr Array niemals mutieren. Da dies gegen das funktionale Programmiermuster ist. Sie können ein neues Array erstellen, ohne auf das Array zu verweisen, dessen Daten Sie mithilfe der ECMAScript 6-Methode ändern möchten filter.

var myArray = [1, 2, 3, 4, 5, 6];

Angenommen, Sie möchten 5aus dem Array entfernen , können Sie dies einfach folgendermaßen tun:

myArray = myArray.filter(value => value !== 5);

Dadurch erhalten Sie ein neues Array ohne den Wert, den Sie entfernen möchten. Das Ergebnis wird also sein:

 [1, 2, 3, 4, 6]; // 5 has been removed from this array

Zum weiteren Verständnis können Sie die MDN-Dokumentation zu Array.filter lesen .

Adeel Imran
quelle
21

Ein modernerer ECMAScript 2015- Ansatz (früher bekannt als Harmony oder ES 6). Gegeben:

const items = [1, 2, 3, 4];
const index = 2;

Dann:

items.filter((x, i) => i !== index);

Nachgeben:

[1, 2, 4]

Sie können Babel und einen Polyfill-Dienst verwenden, um sicherzustellen, dass dies in allen Browsern gut unterstützt wird.

bjfletcher
quelle
4
Beachten Sie, dass .filterein neues Array zurückgegeben wird, was nicht genau dem Entfernen des Elements aus demselben Array entspricht. Der Vorteil dieses Ansatzes besteht darin, dass Sie Array-Methoden miteinander verketten können. zB:[1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]
CodeOcelot
Großartig, wenn ich 600.000 Elemente im Array habe und die ersten 50.000 entfernen möchte, können Sie sich diese Langsamkeit vorstellen? Dies ist keine Lösung, es besteht Bedarf an Funktionen, die nur Elemente entfernen und nichts zurückgeben.
dev1223
@Seraph Dafür möchten Sie wahrscheinlich spliceoder verwenden slice.
Bjfletcher
@bjfletcher Das ist noch besser, wenn Sie sie entfernen, weisen Sie einfach 50.000 Elemente zu und werfen Sie sie irgendwo hin. (mit Slice 550K-Elementen, aber ohne sie aus dem Fenster zu werfen).
dev1223
Ich würde die Antwort von bjfletcher vorziehen, die so kurz sein könnte wie items= items.filter(x=>x!=3). Außerdem gab das OP keine Anforderung für große Datenmengen an.
Runsun
21

Sie haben 1 bis 9 im Array und möchten 5 entfernen. Verwenden Sie den folgenden Code:

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return m !== 5;
});

console.log("new Array, 5 removed", newNumberArray);


Wenn Sie mehrere Werte verwenden möchten. Beispiel: - 1,7,8

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return (m !== 1) && (m !== 7) && (m !== 8);
});

console.log("new Array, 1,7 and 8 removed", newNumberArray);


Wenn Sie einen Array-Wert in einem Array entfernen möchten. Beispiel: [3,4,5]

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var removebleArray = [3,4,5];

var newNumberArray = numberArray.filter(m => {
    return !removebleArray.includes(m);
});

console.log("new Array, [3,4,5] removed", newNumberArray);

Enthält unterstützten Browser ist Link .

Thilina Sampath
quelle
19

Ich weiß, dass es bereits viele Antworten gibt, aber viele davon scheinen das Problem zu komplizieren. Hier ist eine einfache, rekursive Methode zum Entfernen aller Instanzen eines Schlüssels - ruft self auf, bis der Index nicht gefunden wird. Ja, es funktioniert nur in Browsern mit indexOf, aber es ist einfach und kann leicht polygefüllt werden.

Standalone-Funktion

function removeAll(array, key){
    var index = array.indexOf(key);

    if(index === -1) return;

    array.splice(index, 1);
    removeAll(array,key);
}

Prototyp-Methode

Array.prototype.removeAll = function(key){
    var index = this.indexOf(key);

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}
wharding28
quelle
Nur eine Anmerkung, 1 Einschränkung bei dieser Methode ist das Potenzial für Stapelüberläufe. Wenn Sie nicht mit massiven Arrays arbeiten, sollten Sie kein Problem haben.
Wharding28
Aber warum eine Rückkehr in die Mitte? Es ist effektiv eine goto Aussage.
Peter Mortensen
18

Sie können eine Rückwärtsschleife ausführen, um sicherzustellen, dass die Indizes nicht durcheinander gebracht werden, wenn mehrere Instanzen des Elements vorhanden sind.

var myElement = "chocolate";
var myArray = ['chocolate', 'poptart', 'poptart', 'poptart', 'chocolate', 'poptart', 'poptart', 'chocolate'];

/* Important code */
for (var i = myArray.length - 1; i >= 0; i--) {
    if (myArray[i] == myElement) myArray.splice(i, 1);
}

Live-Demo

Jeff Noel
quelle