Con la llegada de la nueva especificación ECMAScript 5, Javascript ha implementado de forma nativa una serie de métodos muy útiles para el manejo de sus objetos.
Uno de los más interesante es el depurado de los arrays mediante filter(), algo que hasta ahora precisaba de funciones específicas o del uso de nuestra librería favorita (jQuery, MooTools, etc). Su sintaxis es la siguiente:
array1.filter(callbackfn[, thisArg]) |
Este método devuelve los elementos de un array que cumplen la condición especificada en el callback o primer argumento.
Así, por ejemplo, podemos fácilmente eliminar aquellos elementos nulos o vacíos de un Array.
NOTA: Los elementos nulos o vacíos son aquellos que corresponden con los siguientes valores: false, null, undefined, 0, NaN.
var myArr = [ 'foo', 0, '', undefined, 'blue', null, 5, false, NaN]; myArrClean = myArr.filter(Boolean); // [foo, blue, 5] |
¿Cómo funciona?
Como Boolean es, además de un constructor, una función, devuelve true o false según el valor de su argumento. De este modo, aquellos elementos del array vacíos o nulos, son evaluados como false y excluidos del resultado:
Boolean('foo') // true Boolean(0) // false Boolean(false) // false Boolean(NaN) // false Boolean({}) // true Boolean('false') // true, ya que 'false' es un objeto String. |
Otros métodos
Este método, como comentamos al principio, pertenece a la nueva especificación ECMA, por lo que no está presente en navegadores antiguos como Internet Explorer 8. Para ver una lista completa sobre los navegadores que los soportan, siempre podemos consultar la ECMAScript 5 compatibility table.
Si necesitamos esta función y nuestro navegador no ofrece el soporte, siempre podemos optar por crearla a mano:
Array.prototype.clean = function( deleteValue ) { for ( var i = 0, j = this.length ; i < j; i++ ) { if ( this[ i ] == deleteValue ) { this.splice( i, 1 ); i--; } } return this; }; test = new Array( "", "One", "Two", "", "Three", "", "Four" ); test.clean(""); // ["One", "Two", "Three", "Four"] |
Hemos extendido el objeto nativo Array añadiéndole un nuevo método clean que actúa de una forma similar a filter():
array1.clean( elementToClean ) |
Mediante una comparación no-estricta, la función evalúa cada valor del array con la cadena enviada en el argumento (elementToClean) para, en caso de igualdad, eliminarlo mediante el comando slice.
Actualización
Si sólo pretendemos borrar los falsy values (elementos vacios o falsos), podemos recurrir a una función más sencilla extraída de los comentarios:
function cleanArray( actual ){ var newArray = new Array(); for( var i = 0, j = actual.length; i < j; i++ ){ if ( actual[ i ] ){ newArray.push( actual[ i ] ); } } return newArray; } cleanArray( [ 1, 2, , 3, , 3, , , , , , 4, , 4, , 5, , 6 ] ); // [ 1, 2, 3, 3, 4, 4, 5, 6 ] |
En este caso, en lugar de extender el objeto nativo, hemos creado una función que no acepta argumentos y que filtra todos los valores falsos para devolver un nuevo array limpio.
Más información:
http://ie.microsoft.com/testdrive/HTML5/ECMAScript5Array/Default.html
Hola,
muchas gracias por el post…pero…una pregunta!!….tengo una funcion que borra el array con eso de filter(Boolean), y en Firefox todo va bien….pero….extrañamente cuando llamo esa funcion desde explorer mi codigo no corre….no sé si esto solo sea compatible con FF ?¿ , tengo IE 8 ….que podrá estar mal??
Hola Edward;
ten en cuenta que estamos hablando de la especificación ECMAScript 5, que es relativamente reciente.
Internet Explorer 8, sólo acepta algunas de los nuevos comandos, pero ‘filter’, es precisamente de los que no.
Échale un vistazo a la siguiente tabla y lo compruebas tú mismo:
http://kangax.github.com/es5-compat-table/
Para borrar elementos vacíos de un array en IE8 o inferiores, tienes que crearte una función propia.
Por ejemplo:
muchas gracias por tu pronta respuesta,, es que soy algo nuevo en JS entonces no estaba muy seguro de qué o porque, pero de verdad gracias, probare tu codigo, lo agradezco =)….
Por cierto una pregunta no relacionada si de igual manera pudieras ayudarme a entender….cuando quiero llamar algo como (algunobjeto.childnodes.lenght)…cuando no hay nada……Firefox me regresa como valor «1» y Explorer si me regresa «0» ….entonces no puedo igualar alguna funcion si hago algo como «if(childnodes==0)» ……Explorer si funciona…pero FF no….como puedo resolver eso? porque sucede esa diferencia???….
Muchas gracias nuevamente =)
Hola,
he editado la respuesta anterior porque tenía problemillas formateando el código; ahora se ve correctamente!
Para comprobar si existe una propiedad en un objeto, no utilizamos length porque, como has comprobado, no es consistente en todos los navegadores. En su lugar, puedes revisar un artículo publicado en esta misma web al respecto:
http://www.etnassoft.com/2010/12/25/comprobar-si-una-propiedad-existe-en-un-objeto-js/
Espero te sea de ayuda!
Un saludo.
hola nuevamente,
muchas gracias pro tu codigo de limpiar arreglos con valores falsy, me ha servido de mucho….emm….regresando al tema de hasownproperty…intenté algo como obj.hasownproperty(«childnodes»)…y siempre me regresaba valor negativo….no sé si yo hiciera algo erroneo, pero ya resolví el problema….te cuanto:
yo llamaba un DIV contenedor con un id = «div_contenedor» y mi HTML era algo como
( aqui había un salto de linea…)
entonces…firefox me decia que div_contenedor.childnodes.length = 1 …..pero entonces….cuando cambie mi HTML a:
(sin el salto de linea…)
ahora si FF me decia que div_contenedor.childnodes.lenght = 0 …no puedo creer que ese simple espacio me hiciera dar mil vueltas…hehehe, pero ya está resuelto, de todas formas, te agradezvco mucho tu ayuda, aprendí nuevas cositas =).
Saludos
am….en mi comentario anterior no sale hi HTML…eran unos divs…algo como:
«(abro)» DIV id=»div_contenedor» «(cierro)»
( aqui había un salto de linea…)
«(abro)» «slash / » DIV «(cierro)»
y luego…en el otro codigo….quité el salto de linea…..:
«(abro)» DIV id=»div_contenedor» «(cierro)»»(abro)» «slash / » DIV «(cierro)»
Hola;
efectivamente, un salto de línea se interpreta como contenido; según el intérprete, en HTML es un br, y en Javascript es una cadena de escape. De ahí que te diese un comportamiento raro.
Me alegro de que solucionaras tu código.
Un saludo!