arrays eliminare - Come rimuovo un particolare elemento da un array in JavaScript?




duplicati splice (25)

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

C'è un modo semplice per rimuovere un elemento specifico da un array? L'equivalente di qualcosa come array.remove(int); .

Devo usare il core JavaScript - non sono permessi quadri.


Answers

Hai da 1 a 9 array e vuoi rimuovere 5 usa sotto il codice.

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ù valore ex: - 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, 5 removed", newNumberArray);

Se si desidera rimuovere il valore dell'array in array ex: - [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 è il link


Se hai oggetti complessi nell'array puoi usare i filtri? In situazioni in cui $ .inArray o array.splice non è così facile da usare. Soprattutto se gli oggetti sono forse superficiali nell'array.

Ad esempio se si dispone di un oggetto con un campo ID e si desidera rimuovere l'oggetto da una matrice:

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

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 l'indice non viene trovato. Sì, funziona solo con i browser indexOf, ma è semplice e può essere facilmente riempito.

Funzione autonoma

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

    if(index === -1) return;

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

Metodo prototipo

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

    if(index === -1) return;

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

Puoi usare lodash _.pull (array di matrici), _.pullAt (array di matrici) o _.without (non _.without 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']

Non so come ti stai aspettando che array.remove(int) comporti. Ci sono tre possibilità che posso pensare che potresti volere.

Per rimuovere un elemento di una matrice in un indice i :

array.splice(i, 1);

Se si desidera rimuovere ogni elemento con il number valore dall'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 non esiste più, ma non vuoi che gli indici degli altri elementi cambino:

delete array[i];

Non è necessario utilizzare indexOf o splice . Tuttavia, si comporta 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 indexOf e splice (indexof):

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

Usa solo splice (splice):

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 su oltre 10000 esecuzioni):

indexof è circa 10 volte più lento dello spostamento . Anche se migliorato rimuovendo la chiamata a indexOf in splice, si comporta molto peggio della mossa .

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

Ho un'altra buona soluzione per la rimozione da un array:

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

filter


Modificato il 2016 ottobre

  • Fallo semplice, intuitivo ed esplicito ( https://en.wikipedia.org/wiki/Occam%27s_razor )
  • Fallo immutabile (la matrice originale rimane invariata)
  • Fallo con le funzioni JS standard, se il tuo browser non le supporta - usa polyfill

In questo esempio di codice uso la funzione "array.filter (...)" per rimuovere gli elementi indesiderati dalla matrice, questa funzione non cambia la matrice originale e ne crea una nuova. Se il tuo browser non supporta questa funzione (ad esempio IE prima della versione 9 o Firefox prima della versione 1.5), considera l'utilizzo del filtro polyfill da Mozilla .

Rimozione dell'oggetto (codice ECMA-262 Edition 5 aka oldstyle JS)

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 dell'oggetto (codice ES2015)

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 ES2015 "() => {}" la sintassi della funzione freccia non è supportata in IE affatto, Chrome prima della versione 45, Firefox prima della versione 22, Safari prima della versione 10. Per usare la sintassi ES2015 nei vecchi browser puoi usare BabelJS

Rimozione di più elementi (codice ES2016)

Un ulteriore vantaggio di questo metodo è la possibilità di 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 è supportata in IE affatto, Chrome prima della versione 47, Firefox prima della versione 43, Safari prima della versione 9 e Edge prima della versione 14, quindi qui è polyfill da Mozilla

Rimozione di più elementi (JavaScript ES2018 sperimentale all'avanguardia?)

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


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

Tutto il metodo descritto non modifica l'array originale e ne crea 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 è usare slice() :

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

console.log(filteredItems)

slice() crea una nuova matrice con gli indici che riceve. Creiamo semplicemente una nuova matrice, dall'inizio all'indice che vogliamo rimuovere e concateniamo un'altra matrice dalla prima posizione che segue quella che abbiamo rimosso alla fine dell'array.

Se conosci il valore

In questo caso, una buona opzione è usare 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. Puoi 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 trasferire il codice ES6 in ES5 per renderlo più digeribile ai vecchi browser, ma scrivere codice JavaScript moderno nel tuo codice.

Rimozione di più oggetti

Cosa succede se al posto di un singolo oggetto, vuoi rimuovere molti oggetti?

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

In base al valore

Puoi cercare l'inclusione all'interno della funzione di callback:

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 modificare l'array originale

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

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


Sulla base di tutte le risposte che erano principalmente corrette e tenendo conto delle migliori pratiche suggerite (specialmente non usando direttamente Array.prototype), ho trovato il seguente codice:

function arrayWithout(arr, values) {
  var isArray = function(canBeArray) {
    if (Array.isArray) {
      return Array.isArray(canBeArray);
    }
    return Object.prototype.toString.call(canBeArray) === '[object Array]';
  };

  var excludedValues = (isArray(values)) ? values : [].slice.call(arguments, 1);
  var arrCopy = arr.slice(0);

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

  return arrCopy;
}

Rivedendo la funzione di cui sopra, nonostante il fatto che funzioni bene, ho capito che ci potrebbe essere un miglioramento delle prestazioni. Anche usare ES6 invece di ES5 è un approccio molto migliore. A tal fine, questo è il codice migliorato:

const arrayWithoutFastest = (() => {
  const isArray = canBeArray => ('isArray' in Array) 
    ? Array.isArray(canBeArray) 
    : Object.prototype.toString.call(canBeArray) === '[object Array]';

  let mapIncludes = (map, key) => map.has(key);
  let objectIncludes = (obj, key) => key in obj;
  let includes;

  function arrayWithoutFastest(arr, ...thisArgs) {
    let withoutValues = isArray(thisArgs[0]) ? thisArgs[0] : thisArgs;

    if (typeof Map !== 'undefined') {
      withoutValues = withoutValues.reduce((map, value) => map.set(value, value), new Map());
      includes = mapIncludes;
    } else {
      withoutValues = withoutValues.reduce((map, value) => { map[value] = value; return map; } , {}); 
      includes = objectIncludes;
    }

    const arrCopy = [];
    const length = arr.length;

    for (let i = 0; i < length; i++) {
      // If value is not in exclude list
      if (!includes(withoutValues, arr[i])) {
        arrCopy.push(arr[i]);
      }
    }

    return arrCopy;
  }

  return arrayWithoutFastest;  
})();

Come usare:

const arr = [1,2,3,4,5,"name", false];

arrayWithoutFastest(arr, 1); // will return array [2,3,4,5,"name", false]
arrayWithoutFastest(arr, 'name'); // will return [2,3,4,5, false]
arrayWithoutFastest(arr, false); // will return [2,3,4,5]
arrayWithoutFastest(arr,[1,2]); // will return [3,4,5,"name", false];
arrayWithoutFastest(arr, {bar: "foo"}); // will return the same array (new copy)

Attualmente sto scrivendo un post sul blog in cui ho confrontato diverse soluzioni per Array senza problemi e ho confrontato il tempo necessario per l'esecuzione. Aggiornerò questa risposta con il link una volta che finirò quel post. Solo per farti sapere, ho confrontato quanto sopra contro il lodash senza e nel caso in cui il browser supporti Map, batte lodash! Si noti che non sto usando Array.prototype.indexOfo Array.prototype.includescome avvolgendo i valori exlcude in a Mapo Objectrende più veloce l'interrogazione! ( https://jsperf.com/array-without-benchmark-against-lodash )


Sono abbastanza nuovo su JavaScript e avevo bisogno di questa funzionalità. Ho solo 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. Spero che questo aiuti qualcuno.


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ù facile 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 visualizzare [1, 2, 3, 4, 6]


ES6 e senza mutazione: (ottobre 2016)

const removeByIndex = (list, index) =>
  [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];

Poi :

removeByIndex([33,22,11,44],1) //=> [33,11,44]

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ù ordinate.

Questo elenco risolverà il problema, eliminando anche 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]

Ci sono due approcci principali:

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

  2. elimina : delete anArray[index];

Fai attenzione quando usi delete per un array. È utile cancellare gli attributi degli oggetti ma non è così buono per gli array. È meglio usare la splice per gli array.

Tieni presente che quando usi delete per un array potresti ottenere risultati errati per anArray.length . In altre parole, delete rimuoverà l'elemento ma non aggiornerà il valore della proprietà length.

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

Se sei costretto a usare delete per qualche motivo, dovresti usarlo for each loop quando hai bisogno di eseguire il loop degli array. Di fatto, evitare sempre l'uso di cicli indicizzati, se possibile. In questo modo il codice sarebbe più robusto e meno soggetto a problemi con gli indici.


Troppo vecchio per rispondere, ma può aiutare qualcuno, fornendo un predicato invece di 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;
    }
};

Dai un'occhiata a questo codice. Funziona in 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);

Dipende se vuoi mantenere un posto vuoto o no.

Se vuoi uno slot vuoto, cancella va bene:

delete array[ index ];

Se non lo fai, dovresti usare il metodo di 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 si desideri farlo in un certo ordine, è possibile utilizzare array.pop() per l'ultimo o array.shift() per il primo (ed entrambi restituiscono anche il valore dell'oggetto).

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


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 fare qualcosa come il seguente, invece:

// 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 la ragione principale per cui sto postando questo è di avvertire gli utenti contro l'implementazione alternativa suggerita nei commenti su quella pagina (14 dicembre 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 nel tentativo di rimuovere il penultimo elemento di 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);

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


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 utilizzare Babel e un servizio Polyfill per assicurarti che questo sia ben supportato tra i browser.


Underscore.js può essere utilizzato per risolvere problemi con più browser. Utilizza i metodi del browser in-build, se presenti. Se sono assenti come nel caso delle vecchie versioni di Internet Explorer, usa i propri metodi personalizzati.

Un semplice esempio per rimuovere elementi dalla matrice (dal sito Web):

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

OK, per esempio hai la matrice qui sotto:

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

E vogliamo eliminare il numero 4, puoi semplicemente fare il codice seguente:

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

Se si riutilizza questa funzione, si scrive una funzione riutilizzabile che verrà associata alla funzione di array nativo 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 stai usando l'array sottostante con pochi [5] s nella matrice?

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

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

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 _.without.


Puoi farlo facilmente con il metodo di filter :

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

Questo rimuove tutti gli elementi dall'array e funziona anche più velocemente della combinazione di slice e indexOf


  Array.prototype.removeItem = function(a) {
            for (i = 0; i < this.length; i++) {
                if (this[i] == a) {
                    for (i2 = i; i2 < this.length - 1; i2++) {
                        this[i2] = this[i2 + 1];
                    }
                    this.length = this.length - 1
                    return;
                }
            }
        }

    var recentMovies = ['Iron Man', 'Batman', 'Superman', 'Spiderman'];
    recentMovies.removeItem('Superman');

Un modo più vicino alla tua idea sarebbe quello di utilizzare Array.forEach()quale accetta una funzione di clojure che verrà eseguita per ogni elemento dell'array.

myArray.forEach(
  (item) => {
    // do something 
    console.log(item);
  }
);

Un altro modo percorribile sarebbe utilizzare ciò Array.map()che funziona allo stesso modo ma anche mutatesogni elemento e lo restituisce come:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]




javascript arrays