Come posso rimuovere un elemento specifico da un array?


8299

Ho una serie di numeri e sto usando il .push()metodo per aggiungere elementi ad esso.

Esiste un modo semplice per rimuovere un elemento specifico da un array?

Sto cercando l'equivalente di qualcosa del tipo:

array.remove(number);

Devo usare JavaScript di base . I frame non sono ammessi.

Risposte:


11896

Trova l' indexelemento dell'array che desideri rimuovere utilizzando indexOf, quindi rimuovi quell'indice con splice.

Il metodo splice () modifica il contenuto di un array rimuovendo elementi esistenti e / o aggiungendo nuovi elementi.

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); 

Il secondo parametro di spliceè il numero di elementi da rimuovere. Si noti che splicemodifica la matrice in atto e restituisce una nuova matrice contenente gli elementi che sono stati rimossi.


Per motivi di completezza, ecco le funzioni. La prima funzione rimuove solo una singola occorrenza (cioè rimuovendo la prima corrispondenza di 5da [2,5,9,1,5,8,5]), mentre la seconda funzione rimuove tutte le occorrenze:

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;
}

15
@Peter, sì, potresti avere ragione. Questo articolo spiega di più e presenta una soluzione alternativa per i browser incompatibili: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Tom Wadley,

33
@AlexandreWiechersVaz Naturalmente conserva l'ordine, se non lo facesse sarebbe assolutamente inutile
TheZ

15
Puoi superare il problema di supporto del browser IE includendo il codice indicato qui

15
@AdrianP. array.indexOf(testValue)sull'array vuoto sarà -1, e se stai provando per quello allora nessuna giuntura. Forse la risposta è cambiata da allora.
UpTheCreek

13
IE 7, IE8, IE9, IE10 non sono supportati dalla stessa Microsoft, perché gli sviluppatori Web dovrebbero supportare quei vecchi browser? Mostra solo le notifiche sull'aggiornamento del browser! support.microsoft.com/en-us/lifecycle/…
Lukas Liesis

1268

Non so come ti aspetti array.remove(int)di comportarti. Ci sono tre possibilità che posso pensare che potresti desiderare.

Per rimuovere un elemento di un array in un indice i:

array.splice(i, 1);

Se si desidera rimuovere ogni elemento con valore numberdall'array:

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

Se vuoi solo rendere l'elemento all'indice inon esiste più, ma non vuoi che cambino gli indici degli altri elementi:

delete array[i];

335
deletenon è il modo corretto di rimuovere un elemento da un array!
Felix Kling,

71
@FelixKling Dipende, funziona se vuoi farlo in modo che array.hasOwnProperty(i)ritorni falsee abbia l'elemento in quella posizione di ritorno undefined. Ma ammetto che non è una cosa molto comune voler fare.
Peter Olson,

88
deletenon aggiorna la lunghezza dell'array né cancella realmente l'elemento, lo sostituisce solo con il valore speciale undefined.
Diosney,

34
@diosney Non so cosa intendi quando dici che non cancella davvero l'elemento. Inoltre, fa molto di più che semplicemente sostituire il valore di quell'indice con undefined: rimuove sia l'indice che il valore dall'array, ovvero dopo delete array[0], "0" in arrayrestituirà false.
Peter Olson,

17
@GrantGryczan Siamo spiacenti, non sono d'accordo. Non vedo la necessità di rimuovere questo. Il testo sopra spiega chiaramente cosa fa e aiuta le persone che non sanno cosa deletefa per capire perché non funziona come si aspettano.
Peter Olson,

1207

Modificato il 2016 ottobre

  • Fallo semplice, intuitivo ed esplicito (il rasoio di Occam )
  • Fallo immutabile (l'array originale rimane invariato)
  • Fallo con le funzioni JavaScript standard, se il tuo browser non le supporta - usa polyfill

In questo esempio di codice uso la funzione "array.filter (...)" per rimuovere elementi indesiderati da un array. Questa funzione non modifica l'array originale e ne crea uno nuovo. Se il tuo browser non supporta questa funzione (ad es. Internet Explorer prima della versione 9 o Firefox prima della versione 1.5), considera l'utilizzo del filtro Polyfill di Mozilla .

Rimozione di un elemento (codice ECMA-262 Edizione 5 aka 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 ]

Rimozione elemento (codice ECMAScript 6)

let value = 3

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

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

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

IMPORTANTE ECMAScript 6 "() => {}" La sintassi della funzione freccia non è affatto supportata in Internet Explorer, Chrome prima della versione 45, Firefox prima della versione 22 e Safari prima della versione 10. Per usare la sintassi ECMAScript 6 nei vecchi browser puoi usare BabelJS .


Rimozione di più elementi (codice ECMAScript 7)

Un ulteriore vantaggio di questo metodo è che è possibile rimuovere più elementi

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 ]

IMPORTANTE La funzione "array.includes (...)" non è affatto supportata in Internet Explorer, Chrome prima della versione 47, Firefox prima della versione 43, Safari prima della versione 9 e Edge prima della versione 14, quindi ecco il polyfill di Mozilla .

Rimozione di più elementi (in futuro, forse)

Se la proposta "Sintassi vincolante" viene mai accettata, sarai in grado di farlo:

// 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 ]

Provalo tu stesso in BabelJS :)

Riferimento


6
ma, a volte vogliamo rimuovere l'elemento dall'array originale (non immutabile), ad esempio l'array utilizzato nella direttiva Angular 2 * ngFor
Ravinder Payal

43
Meglio della soluzione accettata perché non presuppone una sola occorrenza di una partita e l'immutabilità è preferibile
Greg

13
filterdeve essere molto più lento per un array grande però?
Nathan,

3
Qual è il punto di immutabilità menzionato se hai usato l'assegnazione della stessa variabile nei tuoi esempi? :)
mench

12
Questa è un'ottima risposta Splice è una funzione specializzata per la mutazione e non il filtraggio. filterpotrebbe avere prestazioni più lente ma è un codice più sicuro e migliore. Inoltre, puoi filtrare per indice specificando un secondo argomento nel lambda:arr.filter((x,i)=>i!==2)
Matteo

449

Dipende se vuoi mantenere un posto vuoto o meno.

Se si desidera uno slot vuoto, l'eliminazione va bene:

delete array[index];

In caso contrario, è necessario utilizzare il metodo splice :

array.splice(index, 1);

E se hai bisogno del valore di quell'elemento, puoi semplicemente memorizzare l'elemento dell'array restituito:

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

Nel caso in cui tu voglia farlo in un certo ordine, puoi usarlo array.pop()per l'ultimo o array.shift()per il primo (ed entrambi restituiscono anche il valore dell'articolo).

E se non conosci l'indice dell'articolo, puoi usarlo array.indexOf(item)per ottenerlo (in a if()per ottenere un oggetto o in a while()per ottenerli tutti). array.indexOf(item)restituisce l'indice o -1 se non trovato. 


25
deletenon è il modo corretto di rimuovere un elemento da un array !!
Progo,

16
Se si desidera "svuotare uno slot", utilizzare array[index] = undefined;. L'uso deletedistruggerà l'ottimizzazione.
Bergi,

4
@Jakub ottimo commento perché per capire che ho perso molto tempo e ho pensato che il mio codice dell'applicazione fosse in qualche modo rotto ...
Pascal,

L'ultimo paragrafo con la spiegazione di ciò che ottieni da indexOf è stato davvero utile
A. D'Alfonso,

277

Un amico stava riscontrando problemi in Internet Explorer 8 e mi ha mostrato cosa ha fatto. Gli ho detto che era sbagliato, e mi ha detto che ha ottenuto la risposta qui. L'attuale risposta principale non funzionerà in tutti i browser (ad esempio Internet Explorer 8) e rimuoverà solo la prima occorrenza dell'elemento.

Rimuovere TUTTE le istanze da un array

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

Passa attraverso l'array all'indietro (poiché gli indici e la lunghezza cambieranno man mano che gli elementi vengono rimossi) e rimuove l'elemento se viene trovato. Funziona in tutti i browser.


11
@sroes non dovrebbe essere perché il ciclo inizia i = arr.length -1o lo i--rende uguale all'indice massimo. arr.lengthè solo un valore iniziale per i. i--sarà sempre sincero (e diminuendo di 1 ad ogni ciclo op) fino a quando non sarà uguale 0(un valore di falsy) e il ciclo si fermerà quindi.
gmajivu,

1
La seconda funzione è piuttosto inefficiente. Ad ogni iterazione "indexOf" inizierà la ricerca dall'inizio della matrice.
ujeenator,

3
@AmberdeBlack, in una raccolta con più di 1 occorrenza di elemento , è molto meglio chiamare invece il metodo di filtroarr.filter(function (el) { return el !== item }) , evitando la necessità di mutare l'array più volte. Ciò consuma un po 'più di memoria, ma funziona in modo molto più efficiente, poiché c'è meno lavoro da fare.
Eugene Kuzmenko,

1
@AlJey, è disponibile solo da IE9 +. C'è ancora la possibilità che non funzioni.
ujeenator,

1
Questa risposta ha funzionato per me perché avevo bisogno di diversi elementi rimossi ma non in un ordine particolare. La progressione all'indietro del ciclo for consente di rimuovere perfettamente gli elementi dall'array.
mintedsky,

172

Esistono due approcci principali:

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

  2. cancellare :delete anArray[index];

Fare attenzione quando si utilizza Elimina per un array. È utile per eliminare gli attributi degli oggetti, ma non per gli array. È meglio usare spliceper array.

Tienilo a mente quando lo usi delete per un array è possibile ottenere risultati errati per anArray.length. In altre parole, deleterimuoverebbe l'elemento, ma non aggiornerebbe il valore della proprietà length.

Puoi anche aspettarti di avere buchi nei numeri di indice dopo aver usato Elimina, ad esempio potresti finire con avere indici 1, 3, 4, 8, 9 e 11 e lunghezza com'era prima di usare Elimina. In tal caso, tutti indicizzatifor loop arresterebbero in modo anomalo, poiché gli indici non sono più sequenziali.

Se si è costretti a utilizzare deleteper qualche motivo, è necessario utilizzare i for eachloop quando è necessario eseguire il loop tra gli array. È un dato di fatto, evitare sempre l'uso di forcicli indicizzati , se possibile. In questo modo il codice sarebbe più robusto e meno soggetto a problemi con gli indici.


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)


14
Non sono un grande fan di questo approccio. Se finisci per usare librerie o framework diversi, possono finire in conflitto tra loro.
Charlie Kilian,


10
Se si sta eseguendo un'operazione for insu un array, si è già verificato un problema.
Zirak,

2
se lo fai for insu array, hai già problemi più grandi.
Rainb

uso Object.defineProperty stackoverflow.com/a/35518127/3779853 e si sta bene ad andare.
phil294,

105

Non è necessario utilizzare indexOfo splice. Tuttavia, funziona meglio se si desidera rimuovere solo un'occorrenza di un elemento.

Trova e sposta (sposta):

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;
}

Usa indexOfe splice(indexof):

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

Usa solo splice(giunzione):

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

Run-time su nodejs per array con 1000 elementi (media oltre 10000 esecuzioni):

indexof è circa 10 volte più lento di mossa . Anche se migliorato rimuovendo la chiamata a indexOfin splice , funziona molto peggio di spostarsi .

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

5
Sembra che il metodo 'move' presentato qui dovrebbe funzionare in tutti i browser ed evita anche di creare un array aggiuntivo; la maggior parte delle altre soluzioni qui presenta uno o entrambi questi problemi. Penso che questo meriti molti più voti, anche se non sembra "carino".
sockmonk,

73

Ciò fornisce un predicato anziché un valore.

NOTA: aggiornerà l'array specificato e restituirà le righe interessate.

uso

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

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

Definizione

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;
    }
};

Non so che hai bisogno del controllo -1 (i> -1). Inoltre, penso che queste funzioni agiscano più come un filtro che come una rimozione. Se si passa a row.id === 5, si otterrà un array con solo id 5, quindi sta facendo il contrario di remove. Sarebbe bello in ES2015: var result = ArrayHelper.remove (myArray, row => row.id === 5);
Cosa sarebbe bello,

@WhatWouldBeCool questa funzione modifica l'array originale e restituisce l'elemento rimosso invece di copiare il risultato in un nuovo array
amd

68

Puoi farlo facilmente con il metodo di filtro :

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

Ciò rimuove tutti gli elementi dall'array e funziona anche più velocemente di una combinazione di slicee indexOf.


3
Hai una fonte su ciò che è più veloce?
user3711421

2
Bella soluzione. Ma come hai sottolineato, ma è importante renderlo calvo, non produce lo stesso risultato di slice e indexOf poiché rimuoverà tutte le occorrenze di 1
user3711421

1
@utente3711421 questo perché solo slice e indexOf non fanno ciò che vuole "rimuovere un elemento specifico". Rimuove l'elemento solo una volta, questo rimuove un elemento specifico, non importa quanti di essi ne hai
Salvador Dali,

66

John Resig ha pubblicato una buona implementazione :

// 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);
};

Se non vuoi estendere un oggetto globale, puoi invece fare qualcosa del tipo seguente:

// 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);
};

Ma il motivo principale per cui sto pubblicando questo è di mettere in guardia gli utenti dall'implementazione alternativa suggerita nei commenti su quella pagina (14 dic 2007):

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;
};

All'inizio sembra funzionare bene, ma attraverso un processo doloroso ho scoperto che fallisce quando provo a rimuovere il penultimo elemento in un array. Ad esempio, se si dispone di un array di 10 elementi e si tenta di rimuovere il nono elemento con questo:

myArray.remove(8);

Si finisce con un array di 8 elementi. Non so perché, ma ho confermato che l'implementazione originale di John non ha questo problema.


Ho appena imparato a fatica perché è una buona idea usare Object.prototype.hasOwnPropertysempre ¬¬
Davi Fiamenghi,

64

Underscore.js può essere utilizzato per risolvere problemi con più browser. Utilizza metodi browser incorporati, se presenti. Se sono assenti come nel caso delle versioni precedenti di Internet Explorer, utilizza i propri metodi personalizzati.

Un semplice esempio per rimuovere elementi dall'array (dal sito Web):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]

sebbene elegante e conciso, OP ha chiaramente menzionato solo il core JS
EigenFool

64

Puoi usare ES6. Ad esempio per eliminare il valore '3' in questo caso:

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

Produzione :

["1", "2", "4", "5", "6"]

4
Questa risposta è buona perché crea una copia dell'array originale, invece di modificare direttamente l'originale.
Claudio Holanda,

Nota: Array.prototype.filter è ECMAScript 5.1 (No IE8). per soluzioni più specifiche: stackoverflow.com/a/54390552/8958729
Chang

54

Se si desidera un nuovo array con le posizioni eliminate rimosse, è sempre possibile eliminare l'elemento specifico e filtrare l'array. Potrebbe essere necessaria un'estensione dell'oggetto array per i browser che non implementano il metodo di filtro, ma a lungo termine è più semplice poiché tutto ciò che fai è questo:

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

Dovrebbe essere visualizzato [1, 2, 3, 4, 6].


45

Dai un'occhiata a questo codice. Funziona su tutti i principali browser .

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

Chiama questa funzione

remove_item(array,value);

4
@RolandIllig Tranne l'uso di un for in-loop e il fatto che lo script potrebbe essere interrotto in precedenza, restituendo direttamente il risultato dal loop. I voti sono ragionevoli;)
yckart il

1
Questo è un approccio eccellente per piccoli array. Funziona in ogni browser, utilizza un codice minimo e intuitivo e senza framework, shim o polyfill extra complessi.
Beejor,

Dovrei anche ribadire il commento di Yckart sul fatto che for( i = 0; i < arr.length; i++ )sarebbe un approccio migliore poiché conserva gli indici esatti rispetto all'ordine in cui il browser decide di memorizzare gli articoli (con for in). In questo modo è anche possibile ottenere l'indice di array di un valore se necessario.
Beejor,

41

Puoi usare lodash _.pull (array di mutate), _.pullAt (array di mutate) o _.senza (non muta array),

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']

2
Non è il JS di base come richiesto dall'OP, vero?
un utente non descrittivo,

12
@ utente non descrittivo Hai ragione. Ma molti utenti come me vengono qui alla ricerca di una risposta generale non solo per l'OP.
Chun Yang,

@ChunYang Hai perfettamente ragione. Sto già usando lodash, perché non usarlo solo se fa risparmiare tempo.
int-i

38

ES6 e senza mutazione: (ottobre 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)


Perché non usare solo filterallora? array.filter((_, index) => index !== removedIndex);.
user4642212

@ user4642212 hai ragione! inoltre, mi è piaciuto il carattere di sottolineatura dello stile Golang
Abdennour TOUMI

36

La rimozione di un particolare elemento / stringa da un array può essere eseguita in una riga:

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

dove:

theArray : l'array da cui vuoi rimuovere qualcosa di particolare

stringToRemoveFromArray : la stringa che si desidera rimuovere e 1 è la quantità di elementi che si desidera rimuovere.

NOTA : Se "stringToRemoveFromArray" non si trova nell'array, questo rimuoverà l'ultimo elemento dell'array.

È sempre buona norma verificare se l'elemento esiste nell'array prima di rimuoverlo.

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

Se hai accesso alle versioni più recenti di Ecmascript sui computer del tuo client (ATTENZIONE, potrebbe non funzionare su stazioni precedenti):

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

Dove "3" è il valore che si desidera rimuovere dall'array. L'array diventerebbe quindi:['1','2','4','5','6']


Questa è la risposta che ha funzionato per me quando ho cercato di aggiornare un array in base alla commutazione del pulsante di opzione.
jdavid05,

4
Attenzione, se "stringToRemoveFromArray"non si trova nel proprio array, questo rimuoverà l'ultimo elemento dell'array.
Fusion

35

Ecco alcuni modi per rimuovere un elemento da un array usando JavaScript .

Tutti i metodi descritti non mutano l'array originale e ne creano invece uno nuovo.

Se conosci l'indice di un articolo

Supponiamo di avere un array e di voler rimuovere un elemento in posizione i.

Un metodo consiste nell'utilizzare 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()crea un nuovo array con gli indici che riceve. Creiamo semplicemente un nuovo array, dall'inizio all'indice che vogliamo rimuovere, e concateniamo un altro array dalla prima posizione successiva a quello che abbiamo rimosso fino alla fine dell'array.

Se conosci il valore

In questo caso, è consigliabile utilizzare una buona opzione filter(), che offre un approccio più dichiarativo :

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

console.log(filteredItems)

Questo utilizza le funzioni freccia ES6. È possibile utilizzare le funzioni tradizionali per supportare i browser più vecchi:

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

console.log(filteredItems)

oppure puoi usare Babel e trascrivere il codice ES6 su ES5 per renderlo più digeribile ai vecchi browser, ma scrivere JavaScript moderno nel tuo codice.

Rimozione di più elementi

Che cosa succede se invece di un singolo articolo, desideri rimuovere molti elementi?

Troviamo la soluzione più semplice.

Per indice

Puoi semplicemente creare una funzione e rimuovere elementi in serie:

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)

Per valore

È possibile cercare l'inclusione all'interno della funzione di richiamata:

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)

Evitare di mutare l'array originale

splice()(da non confondere slice()) muta l'array originale e dovrebbe essere evitato.

(originariamente pubblicato su https://flaviocopes.com/how-to-remove-item-from-array/ )


34

OK, ad esempio hai l'array di seguito:

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

E vogliamo cancellare il numero 4. Puoi semplicemente usare il codice qui sotto:

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

Se stai riutilizzando questa funzione, scrivi una funzione riutilizzabile che verrà collegata alla funzione di matrice nativa come di seguito:

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];
}

Ma che ne dici se hai l'array sottostante invece con qualche [5] s nell'array?

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

Abbiamo bisogno di un ciclo per controllarli tutti, ma un modo più semplice ed efficiente è utilizzare le funzioni JavaScript integrate, quindi scriviamo una funzione che utilizza invece un filtro come di seguito:

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]

Inoltre ci sono librerie di terze parti che ti aiutano a farlo, come Lodash o Underscore. Per maggiori informazioni, guarda lodash _.pull, _.pullAt o _. senza.


C'è un piccolo errore di battitura. Per favore Correggi. this.splice(num.indexOf(x), 1);=>this.splice(this.indexOf(x), 1);
TheGwa

Si prega di non aumentare i built-in (allegare funzioni a Array.prototype) in JavaScript. Questa è ampiamente considerata una cattiva pratica.
aikeru,

Sono d'accordo che non è la cosa migliore da fare al mondo, ma in questo caso come potresti passarlo alla funzione?
Alireza,

Dovresti controllare l'indice. Se index = -1, splice (-1,1) rimuoverà l'ultimo elemento
Richard Chan il

29

Sono abbastanza nuovo su JavaScript e avevo bisogno di questa funzionalità. Ho semplicemente scritto questo:

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

Quindi quando voglio usarlo:

//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");

Uscita: come previsto. ["item1", "item1"]

Potresti avere esigenze diverse da me, quindi puoi facilmente modificarlo per adattarle a loro. Spero che questo aiuti qualcuno.


1
Questo avrà un comportamento terribile se l'array è veramente lungo e ci sono diverse istanze dell'elemento in esso. Il metodo indexOf dell'array inizierà ogni volta all'inizio, quindi il costo sarà O (n ^ 2).
Zag


27

Se nella matrice sono presenti oggetti complessi, è possibile utilizzare i filtri? In situazioni in cui $ .inArray o array.splice non sono così facili da usare. Soprattutto se gli oggetti sono forse poco profondi nell'array.

Ad esempio, se si dispone di un oggetto con un campo Id e si desidera che l'oggetto venga rimosso da un array:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});

È così che mi piace farlo. Utilizzando una funzione freccia può essere una riga. Sono curioso delle prestazioni. Inoltre non vale nulla che questo sostituisca l'array. Qualsiasi codice con riferimento al vecchio array non noterà la modifica.
joeytwiddle,

27

Voglio rispondere in base a ECMAScript 6 . Supponiamo che tu abbia un array come di seguito:

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

Se si desidera eliminare in un indice speciale come 2, scrivere il codice seguente:

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

Ma se vuoi eliminare un oggetto speciale come 3e non conosci il suo indice, fai come di seguito:

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

Suggerimento : utilizzare una funzione freccia per richiamare il filtro a meno che non si ottenga un array vuoto.


25

Aggiornamento: questo metodo è consigliato solo se non è possibile utilizzare ECMAScript 2015 (precedentemente noto come ES6). Se puoi usarlo, altre risposte qui forniscono implementazioni molto più accurate.


Questa sintesi risolverà il tuo problema e inoltre eliminerà tutte le occorrenze dell'argomento anziché solo 1 (o un valore specificato).

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;
}

Uso:

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]

25

Prestazione

Oggi (2019-12-09) conduco test delle prestazioni su macOS v10.13.6 (High Sierra) per le soluzioni scelte. Mostro delete(A), ma non lo uso rispetto ad altri metodi, perché ha lasciato spazio vuoto nell'array.

Le conclusioni

  • la soluzione più veloce è array.splice(C) (tranne Safari per array di piccole dimensioni dove ha la seconda volta)
  • per array di grandi dimensioni, array.slice+splice(H) è la soluzione immutabile più veloce per Firefox e Safari; Array.from(B) è il più veloce in Chrome
  • le soluzioni mutabili sono in genere 1,5x-6x più veloci di quelle immutabili
  • per i tavolini su Safari, sorprendentemente la soluzione mutabile (C) è più lenta della soluzione immutabile (G)

Dettagli

Nei test rimuovo l'elemento centrale dall'array in diversi modi. Le soluzioni A, C sono in atto. La B, D, E, F, G, H sono immutabili.

Risultati per array con 10 elementi

Inserisci qui la descrizione dell'immagine

In Chrome la array.splice(C) è la soluzione sul posto più veloce. La array.filter(D) è la soluzione immutabile più veloce. Il più lento è array.slice(F). Puoi eseguire il test sulla tua macchina qui .

Risultati per array con 1.000.000 di elementi

Inserisci qui la descrizione dell'immagine

In Chrome, la array.splice(C) è la soluzione sul posto più veloce (la delete(C) è simile, ma ha lasciato uno slot vuoto nell'array (quindi non esegue una "rimozione completa")). Il array.slice-splice(H) è la soluzione più veloce immutabili. Il più lento è array.filter(D ed E). Puoi eseguire il test sulla tua macchina qui .

Confronto per browser: Chrome v78.0.0, Safari v13.0.4 e Firefox v71.0.0

Inserisci qui la descrizione dell'immagine


24

Non dovresti mai mutare l'array. Poiché questo è contro il modello di programmazione funzionale. È possibile creare un nuovo array senza fare riferimento all'array di cui si desidera modificare i dati utilizzando il metodo ECMAScript 6 filter;

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

Supponiamo di voler rimuovere 5dall'array, puoi semplicemente farlo in questo modo:

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

Questo ti darà un nuovo array senza il valore che volevi rimuovere. Quindi il risultato sarà:

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

Per ulteriori informazioni è possibile leggere la documentazione MDN su Array.filter .


21

Un approccio più moderno, ECMAScript 2015 (precedentemente noto come Harmony o ES 6). Dato:

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

Poi:

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

cedendo:

[1, 2, 4]

Puoi usare Babel e un servizio polyfill per assicurarti che questo sia ben supportato su tutti i browser.


4
Si noti che .filterrestituisce un nuovo array, che non è esattamente uguale alla rimozione dell'elemento dallo stesso array. Il vantaggio di questo approccio è che è possibile concatenare i metodi array. ad esempio:[1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]
CodeOcelot,

Fantastico, se ho 600k elementi nell'array e voglio rimuovere i primi 50k, puoi immaginare quella lentezza? Questa non è una soluzione, c'è bisogno di una funzione che rimuove semplicemente gli elementi e non restituisce nulla.
dev1223,

@Seraph Per quello, probabilmente vorresti usare spliceo slice.
bjfletcher,

@bjfletcher È ancora meglio, in fase di rimozione, allocare 50K elementi e lanciarli da qualche parte. (con gli elementi slice 550K, ma senza gettarli dalla finestra).
dev1223

Preferirei la risposta di Bjfletcher, che potrebbe essere breve items= items.filter(x=>x!=3). Inoltre, l'OP non ha indicato alcun requisito per un set di dati di grandi dimensioni.
corre il

21

Nell'array sono presenti da 1 a 9 e si desidera rimuovere 5. Utilizzare il codice seguente:

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);


Se si desidera più valori. Esempio: - 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);


Se si desidera rimuovere un valore di array in un array. Esempio: [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);

Include il browser supportato è link .


19

So che ci sono già molte risposte, ma molte sembrano complicare troppo il problema. Ecco un modo semplice e ricorsivo per rimuovere tutte le istanze di una chiave: chiama self fino a quando non viene trovato l'indice. Sì, funziona solo con i browser indexOf, ma è semplice e può essere facilmente polifillato.

Funzione autonoma

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

    if(index === -1) return;

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

Metodo del prototipo

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

    if(index === -1) return;

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

Solo una nota, 1 avvertenza con questo metodo è il potenziale per overflow dello stack. A meno che tu non stia lavorando con enormi matrici, non dovresti avere problemi.
Wharding28,

Ma perché un ritorno nel mezzo? È effettivamente una dichiarazione goto.
Peter Mortensen,

18

Puoi fare un ciclo indietro per assicurarti di non rovinare gli indici, se ci sono più istanze dell'elemento.

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);
}

Dimostrazione dal vivo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.