Eliminar elementos vacíos de una matriz en Javascript

1353

¿Cómo elimino elementos vacíos de una matriz en JavaScript?

¿Existe una forma sencilla o tengo que recorrerla y eliminarla manualmente?

2
  • 19
    Sería útil si su pregunta hubiera especificado exactamente lo que quiere decir con "elementos vacíos", ya que la mayoría de las respuestas aquí interpretan eso incorrectamente (en mi humilde opinión) para significar elementos "falsos". NB: hay una diferencia entre lo que obtienes var a = [,,]y var a = [undefined, undefined]. El primero está realmente vacío, pero el último en realidad tiene dos claves, pero con undefinedvalores. Alnitak 29 dic 2015 a las 11:30
  • No es una respuesta, pero diría que es una mejor práctica tratar de evitar null/ undefineden una matriz en este primer lugar tanto como sea posible. Por ejemplo, si sus nullmensajes de correo electrónico provienen de mapear otra matriz con la función de mapa regresando nullpara ciertos elementos, intente Array.filtereliminar esos elementos antes de ejecutar el mapa. Hace que su código sea más legible / autodocumentado. Obviamente, esto no funciona para todos los casos de uso, pero se puede aplicar a muchos. Luke Redmore 11 de agosto a las 17:01
1359

EDITAR: Esta pregunta fue respondida hace casi nueve años cuando no había muchos métodos incorporados útiles en Array.prototype.

Ahora, ciertamente, te recomendaría que uses el filtermétodo.

Tenga en cuenta que este método le devolverá una nueva matriz con los elementos que pasan los criterios de la función de devolución de llamada que le proporciona.

Por ejemplo, si desea eliminar nullo undefinedvalores:

var array = [0, 1, null, 2, "", 3, undefined, 3,,,,,, 4,, 4,, 5,, 6,,,,];

var filtered = array.filter(function (el) {
  return el != null;
});

console.log(filtered);

Dependerá de lo que considere "vacío", por ejemplo, si estuviera tratando con cadenas, la función anterior no eliminaría los elementos que son una cadena vacía.

Un patrón típico que veo utiliza a menudo es eliminar los elementos que son Falsy , que incluyen una cadena vacía "", 0, NaN, null, undefined, y false.

Puede pasar al filtermétodo, la Booleanfunción constructora o devolver el mismo elemento en la función de criterios de filtrado, por ejemplo:

var filtered = array.filter(Boolean);

O

var filtered = array.filter(function(el) { return el; });

En ambos sentidos, esto funciona porque el filtermétodo en el primer caso, llama al Booleanconstructor como una función, convirtiendo el valor, y en el segundo caso, el filtermétodo convierte internamente el valor de retorno de la devolución de llamada implícitamente en Boolean.

Si está trabajando con matrices dispersas y está tratando de deshacerse de los "agujeros", puede usar el filtermétodo pasando una devolución de llamada que devuelve verdadero, por ejemplo:

var sparseArray = [0, , , 1, , , , , 2, , , , 3],
    cleanArray = sparseArray.filter(function () { return true });

console.log(cleanArray); // [ 0, 1, 2, 3 ]

Respuesta anterior: ¡No hagas esto!

Utilizo este método, ampliando el prototipo de Array nativo:

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

test = new Array("", "One", "Two", "", "Three", "", "Four").clean("");
test2 = [1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,];
test2.clean(undefined);

O simplemente puede empujar los elementos existentes a otra matriz:

// Will remove all falsy values: undefined, null, 0, false, NaN and "" (empty string)
function cleanArray(actual) {
  var newArray = new Array();
  for (var i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

cleanArray([1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,]);
17
  • 115
    ADVERTENCIA: La segunda opción eliminará cualquier elemento de una matriz considerada "falsa", es decir, los valores de falso, 0, nulo e indefinido. Esta matriz terminaría sin nada en absoluto: [nulo ,,, 0,, ​​0,0,0, falso, nulo, 0] aunque podría querer los elementos con valores de 0, como en esta matriz: [ 1,0,1,0,0,1]Jason Bunting 11 de nov. De 2008 a las 16:48
  • 5
    Me doy cuenta de eso, por eso solo hablé de la segunda opción. En cuanto al primero, tiene un alcance tan limitado que dudaría en convertirlo en parte del prototipo de Array. Vea la respuesta de Alnitak en esta página para ver algo que sería más ideal. Sin embargo, el tuyo permite el encadenamiento, obviamente. Jason Bunting 11 de nov. De 2008 a las 17:02
  • 1
    Su primera solución es realmente buena si no tiene acceso al método de "filtro". De lo contrario, creo que la respuesta de Alnitak es mejor. Joe Pineda 11 de nov. De 2008 a las 18:06
  • 2
    @AlfaTek: todos, excepto los navegadores más nuevos # 2, tendrán el mejor rendimiento, porque las matrices en JS no son realmente matrices. La splicellamada es realmente cara en los navegadores más antiguos porque tienen que volver a numerar todas las claves de matriz para cerrar la brecha. Alnitak 10 de mayo de 2011 a las 19:35
  • 1
    @David no, en el código moderno debería extender de forma segura el Array.prototypeuso Object.definePropertypara hacer que la nueva función sea una propiedad no enumerable y luego evitar el impacto en el rendimiento causado por poner .hasOwnPropertyen cada bucle. Alnitak 23/11/15 a las 11:57
1466

Maneras simples:

var arr = [1,2,,3,,-3,null,,0,,undefined,4,,4,,5,,6,,,,];


arr.filter(n => n)
// [1, 2, 3, -3, 4, 4, 5, 6]

arr.filter(Number) 
// [1, 2, 3, -3, 4, 4, 5, 6]

arr.filter(Boolean) 
// [1, 2, 3, -3, 4, 4, 5, 6]

o - (solo para elementos de matriz única de tipo "texto")

['','1','2',3,,'4',,undefined,,,'5'].join('').split(''); 
// output:  ["1","2","3","4","5"]

o - Forma clásica: iteración simple

var arr = [1,2,null, undefined,3,,3,,,0,,,[],,{},,5,,6,,,,],
    len = arr.length, i;

for(i = 0; i < len; i++ )
    arr[i] && arr.push(arr[i]);  // copy non-empty values to the end of the array

arr.splice(0 , len);  // cut the array and leave only the non-empty values

arr // [1,2,3,3,[],Object{},5,6]


a través de jQuery:

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

arr = $.grep(arr,function(n){ return n == 0 || n });

arr // [1, 2, 3, 3, 0, 4, 4, 5, 6]


ACTUALIZACIÓN: solo otra forma rápida y genial (usando ES6):

var arr = [1,2,null, undefined,3,,3,,,0,,,4,,4,,5,,6,,,,], 
    temp = [];

for(let i of arr)
    i && temp.push(i); // copy each non-empty value to the 'temp' array

arr = temp;

arr // [1, 2, 3, 3, 4, 4, 5, 6]

Eliminar valores vacíos

['foo', '',,,'',,null, ' ', 3, true, [], [1], {}, undefined, ()=>{}].filter(String)

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
30
  • 36
    El primer soporte de IE para el filtro es el modo estándar IE9. yincrash 2/11/11 a las 2:19
  • 14
    para javascript puro debería serarr = arr.filter(function(n){return n; });ilumin 12 de enero de 2013 a las 8:38
  • 23
    foo.join("").split("")solo parece funcionar si las cadenas son caracteres individualesAtav32 26/07/2013 a las 16:32
  • 11
    Su código JavaScript puro tiene un error. Si la matriz tiene un valor con "0", el valor se filtrará porque "0" es falso. Lo que quieres es: arr.filter (function (n) {return (n! == undefined && n! == null);}); John Kurlak 7/0314 a las 21:55
  • 6
    ES6 puede hacerlo aún más simple arr.filter(e=>e)y esto se puede encadenar por mapa, reducir, etc.Sheepy 9 de febrero de 2015 a las 4:32
254

Si necesita eliminar TODOS los valores vacíos ("", nulo, indefinido y 0):

arr = arr.filter(function(e){return e}); 

Para eliminar valores vacíos y saltos de línea:

arr = arr.filter(function(e){ return e.replace(/(\r\n|\n|\r)/gm,"")});

Ejemplo:

arr = ["hello",0,"",null,undefined,1,100," "]  
arr.filter(function(e){return e});

Regreso:

["hello", 1, 100, " "]

ACTUALIZAR (basado en el comentario de Alnitak)

En algunas situaciones, es posible que desee mantener "0" en la matriz y eliminar cualquier otra cosa (nulo, indefinido y ""), esta es una forma:

arr.filter(function(e){ return e === 0 || e });

Regreso:

["hello", 0, 1, 100, " "]
8
  • Sí, esto es bueno porque elimina "" también. Vladimirs 29 de marzo de 2013 a las 15:51
  • 3
    La función de prueba podría ser un poco más explícita:function(e){return !!e}Koen. 2 de noviembre de 2014 a las 0:45
  • 4
    @Koen Tenga en cuenta que !!eincluirá NaN (a diferencia de 0) donde eno lo haría (como 0). Sheepy 9 de febrero de 2015 a las 4:35
  • En realidad, no responde a la pregunta que se hizo. Alnitak 24/02/15 a las 17:16
  • 2
    O use var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);elimina indefinido, "" y 0Mark Schultheiss 17/04/2016 a las 13:53
140

Simplemente un forro:

[1, false, "", undefined, 2].filter(Boolean); // [1, 2]

o usando underscorejs.org :

_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]
7
  • 1
    Esto es realmente genial. Sin embargo, tengo una pregunta nueva: parece que estás usando un nombre de clase como una llamada de función, ¿eso es encasillado? No he visto esto antes y no estoy seguro de entender por qué el paso Booleanfunciona como una función ...Andrew 3 feb 2013 a las 0:50
  • 9
    Si lo trata Booleancomo una función, simplemente regresará trueo falsesi el valor es verdaderamente / falso. andlrc 7 feb 2013 a las 16:38
  • 9
    No está tratando a Boolean como una función; que es una función. (Una función completamente normal, excepto que está implementada de forma nativa). Alguien necesita investigar un poco sobre el modelo de objetos de JavaScript. ;)ELLIOTTCABLE 24 feb 2015 a las 17:28
  • @ELLIOTTCABLE Voy a dejar esto aquí (true).constructor === Boolean. Y luego dime si podemos hacer esto con otras incorporaciones en JS. ;)) (por supuesto, excluyó los otros 5 constructores incorporados. (Cadena, Matriz, Objeto, Función, Número))andlrc 24 feb 2015 a las 17:33
  • 1
    Fallará ambos si hay un valor 0 en la matrizSai Ram 31 de enero de 2017 a las 6:13
134

Si tiene Javascript 1.6 o posterior, puede usar Array.filteruna return truefunción de devolución de llamada trivial , por ejemplo:

arr = arr.filter(function() { return true; });

ya que .filteromite automáticamente los elementos que faltan en la matriz original.

La página de MDN vinculada anteriormente también contiene una buena versión de verificación de errores filterque se puede usar en intérpretes de JavaScript que no son compatibles con la versión oficial.

Tenga en cuenta que esto no eliminará las nullentradas ni las entradas con un undefinedvalor explícito , pero el OP solicitó específicamente las entradas "faltantes".

7
  • ¡Tienes razón! Puede ser tan simple como esto (¡y funciona!): Test3 = [1,2,, 3,, 3 ,,,, 7 ,,, 7 ,,, 0 ,,, 4,, 4,, 5 ,, 6, indefinido ,, nulo ,,]; printp ("Usando el filtrado nativo de la matriz:", test3.filter (function (value) {return (value == undefined)? 0: 1;})); Joe Pineda 11 de nov. De 2008 a las 18:02
  • 3
    +1 Como dijo Alnitak, tienen el código que se puede usar en el caso de no tener js 1.6 disponibleSameer Alibhai 28/04/10 a las 18:50
  • 3
    @katsh He aclarado - el código anterior hace el trabajo para eliminar las entradas para que no exista valor en absoluto, que (he posteriormente) aprendido es semánticamente diferente al caso de una llave que existe pero que tiene undefinedcomo su valor dado. Alnitak 10 de julio de 2014 a las 7:56
  • 4
    Para eliminar entradas no definidas o nulas, simplemente haga una pequeña modificación ... arr = arr.filter (function (v) {return v;}); Alan CN 6/10/2016 a las 21:13
  • 5
    @AlanCN has perdido completamente mi punto. El OP pidió eliminar las entradas faltantes , mientras que la mayor parte de las respuestas aquí (incorrectamente) eliminan las entradas "falsas". Alnitak 7/10/2016 a las 9:28
92

Para quitar agujeros, debe usar

arr.filter(() => true)
arr.flat(0) // New in ES2019

Para eliminar agujero, nulo y no definido:

arr.filter(x => x != null)

Para eliminar los valores de hole, y, falsy (null, undefined, 0, -0, 0n, NaN, "", false, document.all):

arr.filter(x => x)

arr = [, null, (void 0), 0, -0, 0n, NaN, false, '', 42];
console.log(arr.filter(() => true)); // [null, (void 0), 0, -0, 0n, NaN, false, '', 42]
console.log(arr.filter(x => x != null)); // [0, -0, 0n, NaN, false, "", 42]
console.log(arr.filter(x => x)); // [42]

Nota:

  • Los agujeros son algunos índices de matriz sin elementos.
arr = [, ,];
console.log(arr[0], 0 in arr, arr.length); // undefined, false, 2; arr[0] is a hole
arr[42] = 42;
console.log(arr[10], 10 in arr, arr.length); // undefined, false, 43; arr[10] is a hole

arr1 = [1, 2, 3];
arr1[0] = (void 0);
console.log(arr1[0], 0 in arr1); // undefined, true; a[0] is undefined, not a hole

arr2 = [1, 2, 3];
delete arr2[0]; // NEVER do this please
console.log(arr2[0], 0 in arr2, arr2.length); // undefined, false; a[0] is a hole
  • Todos los métodos anteriores devuelven una copia de la matriz dada, no la modifican en el lugar.
arr = [1, 3, null, 4];
filtered = arr.filter(x => x != null);
console.log(filtered); // [1, 3, 4]
console.log(arr); // [1, 3, null, 4]; not modified
3
  • 3
    Esto debería ocupar un lugar destacado en la respuesta. ¿Puede ampliar lo que quiere decir con agujeros / agujero ...? samayo 9 de enero de 2018 a las 14:43
  • 2
    Los agujeros de @samayo son elementos de matriz sin llenar, es decir,[, ,]Jimmy Obonyo Abor 23/04/18 a las 20:06
  • 1
    Al usar arr.filter(x => x), JS verificará si x es verdadero o falso, es decir if (x), por lo tanto, solo se asignará el valor de veracidad a la nueva lista. KuanYu Chu 21/04/19 a las 11:30
59

La forma limpia de hacerlo.

var arr = [0,1,2,"Thomas","false",false,true,null,3,4,undefined,5,"end"];
arr = arr.filter(Boolean);
// [1, 2, "Thomas", "false", true, 3, 4, 5, "end"]
1
  • 7
    Los elementos vacíos son undefined; esto básicamente elimina todos los valores falsos. pimvdb 26/03/11 a las 17:17
39

ES6 simple

['a','b','',,,'w','b'].filter(v => v);
1
  • 2
    Esto no funciona: [1, 'two', null, undefined, , NaN, false, true, 0].filter(v => v). zipper 3 oct 2019 a las 3:52
38

ES6:

let newArr = arr.filter(e => e);
0
22

Con subrayado / Lodash:

Caso de uso general:

_.without(array, emptyVal, otherEmptyVal);
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);

Con vacíos:

_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]

Consulte la documentación de lodash sin .

1
  • El problema con #compact es que elimina los valores falsos. Entonces, si su matriz contiene valores 0, también se eliminarán. Samuel Brandão 18 de marzo de 2016 a las 9:44
22

En realidad, puede usar ES6+métodos, suponiendo que la matriz está a continuación:

 const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];

Y la respuesta podría ser una de estas dos formas:

  • Primera forma:

    const clearArray = arr.filter(i => i);
    
  • Segunda forma:

    const clearArray = arr.filter(Boolean);
    
0
dieciséis

Si usar una biblioteca es una opción, sé que underscore.js tiene una función llamada compact () http://documentcloud.github.com/underscore/ , también tiene varias otras funciones útiles relacionadas con matrices y colecciones.

Aquí hay un extracto de su documentación:

_.compact(array)

Returns a copy of the array with all falsy values removed. In JavaScript, false, null, 0, "", undefined and NaN are all falsy.

_.compact([0, 1, false, 2, '', 3]);

=> [1, 2, 3]

1
  • 1
    También elimina elementos no vacíos, elementos definidos como 0.Timothy Gu 11/11/2014 a las 4:09
15

@Alnitak

En realidad, Array.filter funciona en todos los navegadores si agrega algún código adicional. Vea abajo.

var array = ["","one",0,"",null,0,1,2,4,"two"];

function isempty(x){
if(x!=="")
    return true;
}
var res = array.filter(isempty);
document.writeln(res.toJSONString());
// gives: ["one",0,null,0,1,2,4,"two"]  

Este es el código que necesita agregar para IE, pero el filtro y la programación funcional vale la pena.

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}
2
  • Esta debería ser la respuesta aceptada, ya que funciona de inmediato. Muchas gracias. Tony 6 de agosto de 2014 a las 21:44
  • 2
    @Tony no, no debería, porque un elemento con una cadena vacía no es lo mismo que un "elemento vacío", siendo este último lo que pidió el OP. Alnitak 24 feb 2015 a las 17:18
14

Como nadie más lo mencionó y la mayoría de las personas han incluido un subrayado en su proyecto, también puede usar _.without(array, *values);.

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
0
8

Puede que le resulte más fácil recorrer su matriz y construir una nueva matriz a partir de los elementos que desea mantener de la matriz que tratando de hacer un bucle y empalmar como se ha sugerido, ya que modifica la longitud de la matriz mientras se está en bucle más puede introducir problemas.

Podrías hacer algo como esto:

function removeFalsyElementsFromArray(someArray) {
    var newArray = [];
    for(var index = 0; index < someArray.length; index++) {
        if(someArray[index]) {
            newArray.push(someArray[index]);
        }
    }
    return newArray;
}

En realidad, aquí hay una solución más genérica:

function removeElementsFromArray(someArray, filter) {
    var newArray = [];
    for(var index = 0; index < someArray.length; index++) {
        if(filter(someArray[index]) == false) {
            newArray.push(someArray[index]);
        }
    }
    return newArray;
}

// then provide one or more filter functions that will 
// filter out the elements based on some condition:
function isNullOrUndefined(item) {
    return (item == null || typeof(item) == "undefined");
}

// then call the function like this:
var myArray = [1,2,,3,,3,,,,,,4,,4,,5,,6,,,,];
var results = removeElementsFromArray(myArray, isNullOrUndefined);

// results == [1,2,3,3,4,4,5,6]

Entiende la idea, entonces podría tener otros tipos de funciones de filtro. Probablemente más de lo que necesitas, pero me sentía generoso ...;)

0
6

¿Qué pasa con esto (ES6): Para eliminar el valor Falsy de una matriz.

var arr = [0,1,2,"test","false",false,true,null,3,4,undefined,5,"end"];

arr.filter((v) => (!!(v)==true));

//output:

//[1, 2, "test", "false", true, 3, 4, 5, "end"]
6

Debe usar el filtro para obtener una matriz sin elementos vacíos. Ejemplo en ES6

const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
4

Al usar la respuesta más votada anterior, el primer ejemplo, obtenía caracteres individuales para longitudes de cadena superiores a 1. A continuación se muestra mi solución para ese problema.

var stringObject = ["", "some string yay", "", "", "Other string yay"];
stringObject = stringObject.filter(function(n){ return n.length > 0});

En lugar de no regresar si no está definido, regresamos si la longitud es mayor que 0. Espero que eso ayude a alguien.

Devoluciones

["some string yay", "Other string yay"]
1
  • +1 ya que esto es muy práctico y exactamente lo que normalmente necesito para trabajar con matrices de cadenas, pero tenga en cuenta que esto elimina los números (si no están en forma de cadena) ya que no tienen una longitud. Por lo tanto, ["", "some string yay", "", "", 123, "Other string yay"].filter(function(n){ return n.length > 0}) //gives your same result removing 123reemplaza esa función. .. con String, irónicamente, deja números pero daría el mismo resultado en su matriz dada. aamarks 24/04/18 a las 15:45
3

Simplemente estoy añadiendo mi voz a la anterior “llamada de ES5 Array..filter()con un constructor mundial” golf-corte, pero se sugiere emplear Objecten lugar de String, Booleano Numbercomo se sugirió anteriormente.

Específicamente, ES5 filter()ya no se activa para undefinedelementos dentro de la matriz; por lo que una función que devuelve universalmente true, que devuelve todos los elementos filter()hits, necesariamente solo devolverá no undefinedelementos:

> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(function(){return true})
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]

Sin embargo, escribir ...(function(){return true;})es más largo que escribir ...(Object); y el valor de retorno del Objectconstructor será, bajo cualquier circunstancia , algún tipo de objeto. A diferencia de los constructores de boxeo primitivos sugeridos anteriormente, ningún valor de objeto posible es falsey y, por lo tanto, en una configuración booleana, Objectes una abreviatura de function(){return true}.

> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(Object)
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]
3
  • 1
    CUIDADO: el filtro (Cadena) y el filtro (Objeto) no filtran nulos o números. Debido a que un constructor también es una función, puede pasar String para filtrar, someArray.filter(String);es decir, a lo que en realidad es equivalente someArray.filter(function(x){ return String(x); });. Si desea eliminar todos los valores falsos, someArray.filter(Boolean);funciona para eliminar 0, -0, NaN, falso, '', nulo e indefinido. robocat 12 mar 13 a las 1:07
  • 1
    Buena respuesta, aunque me pregunto sobre la sobrecarga de rendimiento de llamar al Objectconstructor en lugar del return truemétodo. @robocat el OP pidió que se eliminen los elementos vacíos, no los nulos. Alnitak 24 feb 2015 a las 17:22
  • Prefiero la solución más corta y clara, excepto en bucles estrechos. Preferencia personal, supongo. (=ELLIOTTCABLE 24 feb 2015 a las 17:24
3
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]

1
  • ¡Esta es la forma obviamente correcta de hacerlo y debería estar en la parte superior! Martin Andersson 11 de mayo de 2017 a las 8:22
3

Eliminar todos los elementos vacíos

Si una matriz contiene objetos, matrices y cadenas vacías junto con otros elementos vacíos, podemos eliminarlos con:

const arr = [ [], ['not', 'empty'], {}, { key: 'value' }, 0, 1, null, 2, "", "here", " ", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ]

let filtered = JSON.stringify(
  arr.filter((obj) => {
    return ![null, undefined, ''].includes(obj)
  }).filter((el) => {
    return typeof el != "object" || Object.keys(el).length > 0
  })
)

console.log(JSON.parse(filtered))

Compactación simple (eliminando elementos vacíos de una matriz)

Con ES6:

const arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]

let filtered = arr.filter((obj) => { return ![null, undefined].includes(obj) })

console.log(filtered)

Con JavaScript simple ->

var arr = [0, 1, null, 2, "", 3, undefined, 3, , , , , , 4, , 4, , 5, , 6, , , ,]

var filtered = arr.filter(function (obj) { return ![null, undefined].includes(obj) })

console.log(filtered)
2
  • Oye, solo quería preguntar si hay alguna manera de eliminar elementos nulos de una matriz 2D / anidada en ES 6. Mob_Abominator 4 de agosto de 2020 a las 13:10
  • Hola @Mob_Abominator, ciertamente se puede hacer, prueba esta misma lógica accediendo a la matriz anidada. Zalom 6/08/20 a las 9:25
3

Puede usar el filtro con índice y inoperador

let a = [1,,2,,,3];
let b = a.filter((x,i)=> i in a);

console.log({a,b});
7
  • suponiendo que la matriz contiene números de índice ...? Magne 29/11/20 a las 17:34
  • @Magne en JS, los índices de matrices estándar son números. Los objetos JS pueden contener otras claves además de números. Las matrices JS también son objeto y puede ponerle un par clave-valor, por ejemplo let a=[]; a.abc=1, pero generalmente ningún cuerpo lo hace (es bastante exótico hacerlo, porque en su lugar, las matrices pueden usar, por ejemplo, un objeto {}). Y cuando usa una matriz de una manera tan exótica, los métodos de matriz JS estándar como map, filteretc., ignorarán tales pares clave-valor, mi solución basada en filtery también la ignorará. Es bastante obvio que OP pregunta sobre la matriz JS estándar (porque no menciona un caso de uso tan exótico)Kamil Kiełczewski 29/11/20 a las 18:45
  • sí, no me refería a eso, en realidad, pero gracias por aclarar eso también. Hojeé la parte superior de developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… y creo confusamente que el inoperador devolvió el valor en la matriz. Así que pensé que solo funcionaría si los valores en la matriz eran los mismos que los números de índice por los que se quería filtrar. Pero veo que ahora se inrefiere a las propiedades (como índices), no a los valores, de una matriz. Magne 1 dic.20 a las 13:23
  • 1
    @Magne ok, lo edito ahoraKamil Kiełczewski 1 dic.20 a las 17:39
  • 1
    genial, voté a favor ahora. Magne 1 dic.20 a las 17:52
2

¿Qué hay de eso?

js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6
0
2

Otra forma de hacerlo es aprovechar la propiedad de longitud de la matriz: empaque los elementos no nulos a la 'izquierda' de la matriz y luego reduzca la longitud. Es un algoritmo en el lugar -no asigna memoria, es una lástima para el recolector de basura-, y tiene muy buen comportamiento en el mejor / promedio / peor caso.

Esta solución, en comparación con otras aquí, es entre 2 y 50 veces más rápida en Chrome y de 5 a 50 veces más rápida en Firefox, como puede ver aquí: http://jsperf.com/remove-null-items-from-array

El siguiente código agrega el método 'removeNull' no enumerable al Array, que devuelve 'this' para la conexión en cadena:

var removeNull = function() {
    var nullCount = 0           ;
    var length    = this.length ;
    for (var i=0, len=this.length; i<len; i++) { if (!this[i]) {nullCount++} }
    // no item is null
    if (!nullCount) { return this}
    // all items are null
    if (nullCount == length) { this.length = 0; return this }
    // mix of null // non-null
    var idest=0, isrc=length-1;
    length -= nullCount ;                
    while (true) {
         // find a non null (source) slot on the right
         while (!this[isrc])  { isrc--; nullCount--; } 
         if    (!nullCount) { break }       // break if found all null
         // find one null slot on the left (destination)
         while ( this[idest]) { idest++  }  
         // perform copy
         this[idest]=this[isrc];
         if (!(--nullCount)) {break}
         idest++;  isrc --; 
    }
    this.length=length; 
    return this;
};  

Object.defineProperty(Array.prototype, 'removeNull', 
                { value : removeNull, writable : true, configurable : true } ) ;
4
  • Buena respuesta, ¡aunque sería bueno ver algunos casos de prueba para mostrarlo en acción! Alnitak 24 feb 2015 a las 17:27
  • 2
    Esta respuesta es muy fascinante, pero me recuerda de mirar a una computadora construida en 1945, cuando tengo un teléfono inteligente: arr.filter(e => e). agm1984 8 de septiembre de 2017 a las 5:07
  • @ agm1984 su teléfono inteligente no es inteligenteHernán Eche 4/06/20 a las 15:45
  • Eso puede depender de su definición de smart--como el verbo, para causar un dolor punzante agudo. Esto es relevante debido al dolor físico si uso mi teléfono como arma debido a tu comentario. agm1984 4/06/20 a las 15:57
1

Esto funciona, lo probé en AppJet (puede copiar y pegar el código en su IDE y presionar "recargar" para verlo funcionar, no es necesario crear una cuenta)

/* appjet:version 0.1 */
function Joes_remove(someArray) {
    var newArray = [];
    var element;
    for( element in someArray){
        if(someArray[element]!=undefined ) {
            newArray.push(someArray[element]);
        }
    }
    return newArray;
}

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

print("Original array:", myArray2);
print("Clenased array:", Joes_remove(myArray2) );
/*
Returns: [1,2,3,3,0,4,4,5,6]
*/
1
  • 1
    Esto sólo parece funcionar "por accidente", ya que es el acto de enumerar las claves mediante lo for ... inque en realidad provoca la omisión de elementos faltantes. La prueba de undefinedsolo sirve para eliminar elementos reales que se establecen explícitamente en ese valor. Alnitak 29/12/15 a las 11:28
1
foo = [0, 1, 2, "", , false, 3, "four", null]

foo.filter(function(e) {
    return e === 0 ? '0' : e
})

devoluciones

[0, 1, 2, 3, "four"]
0
1

'Mal uso' del bucle for ... in (object-member). => Solo los valores veraces aparecen en el cuerpo del bucle.

// --- Example ----------
var field = [];

field[0] = 'One';
field[1] = 1;
field[3] = true;
field[5] = 43.68;
field[7] = 'theLastElement';
// --- Example ----------

var originalLength;

// Store the length of the array.
originalLength = field.length;

for (var i in field) {
  // Attach the truthy values upon the end of the array. 
  field.push(field[i]);
}

// Delete the original range within the array so that
// only the new elements are preserved.
field.splice(0, originalLength);
1
  • el código es correcto, el comentario es incorrecto. El acto de usar for ... ines lo que elimina las claves indefinidas de la matriz, pero en realidad no tiene código aquí para aceptar solo valores "verdaderos"Alnitak 15 de enero de 2018 a las 10:45
1

Esto podría ayudarlo: https://lodash.com/docs/4.17.4#remove

var details = [
            {
                reference: 'ref-1',
                description: 'desc-1',
                price: 1
            }, {
                reference: '',
                description: '',
                price: ''
            }, {
                reference: 'ref-2',
                description: 'desc-2',
                price: 200
            }, {
                reference: 'ref-3',
                description: 'desc-3',
                price: 3
            }, {
                reference: '',
                description: '',
                price: ''
            }
        ];

        scope.removeEmptyDetails(details);
        expect(details.length).toEqual(3);

scope.removeEmptyDetails = function(details){
            _.remove(details, function(detail){
                return (_.isEmpty(detail.reference) && _.isEmpty(detail.description) && _.isEmpty(detail.price));
            });
        };
1
var data= { 
    myAction: function(array){
        return array.filter(function(el){
           return (el !== (undefined || null || ''));
        }).join(" ");
    }
}; 
var string = data.myAction(["I", "am","", "working", "", "on","", "nodejs", "" ]);
console.log(string);

Producción:

I am working on nodejs

Eliminará el elemento vacío de la matriz y mostrará otro elemento.

2
  • salida: 'Estoy trabajando en nodejs'. eliminará el elemento vacío de la matriz y mostrará otro elemento. Jitendra virani 21 feb 2018 a las 9:35
  • Mejoré tu respuesta. Intente hacer una respuesta simple, clara y legible;)GGO 21 feb 2018 a las 9:45
1

Todos los elementos vacíos se pueden eliminar de una matriz simplemente usando. array.filter(String); Devuelve todos los elementos no vacíos de una matriz en javascript.

3
  • 1
    Lamentablemente, acepta nullmientras se usa, lo Booleanelimina con cadenas vacías. Paul Watson 10/06/20 a las 14:18
  • 1
    @PaulWatson Sí, desafortunadamente, acepta null como una cadena, pero puede eliminar elementos vacíos de la matriz. Espero que entiendanBhupesh Kumar 3 de julio de 2020 a las 7:35
  • Ni siquiera funciona bien. Se supone que debe eliminar los "elementos no vacíos" (supuestamente, elementos existentes, eliminando todos los espacios vacíos) pero también filtra una cadena vacía y matrices vacías. Si se supone que filtra los valores falsos , en realidad deja nully 0. De cualquier forma que se suponga que funcione ... no. Especialmente si consideramos cualquier cosa que pueda tener una personalización toString()definida que pueda llevar a que otros elementos se consideren falsos cuando no lo son. VLAZ 22 abr a las 17:35