Pergunta

Como faço para remover os elementos vazios de uma matriz em JavaScript?

Existe uma maneira simples, ou eu preciso percorrer-lo e removê-los manualmente?

Foi útil?

Solução

EDIT:. Esta pergunta foi respondida quase nove anos atrás, quando não havia muito útil built-in métodos na Array.prototype

Agora, certamente eu apenas recomendo que você use o método filter.

Leve em mente que este método irá retornar um novo array com os elementos que passam os critérios da função de retorno que você fornece a ele, por exemplo, se você quiser remover valores null ou undefined :

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

Ele vai depender do que você considera ser "vazio", por exemplo, se você estivesse lidando com cordas, a função acima não remover elementos que são uma cadeia vazia.

Um padrão comum que vejo frequentemente utilizado é remover elementos que são Falsas , que incluem um vazio seqüência "", 0, NaN, null, undefined e false.

Você pode simplesmente passar para o método filter, a função de construtor Boolean, ou simplesmente devolver o mesmo elemento na função de critérios de filtro, por exemplo:

var filtered = array.filter(Boolean);

ou

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

Em ambos os sentidos isso funciona porque o método filter no primeiro caso, chama o construtor Boolean como uma função, converter o valor, e no segundo caso, o método filter internamente converte o valor de retorno da chamada de retorno implicitamente Boolean.

Se você está trabalhando com matrizes esparsas, e que você está tentando se livrar dos "buracos", você pode simplesmente usar o método filter passando um callback que retorna verdade, por exemplo:

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

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

velha resposta: Não faça isso

Eu uso este método, estendendo-se o protótipo de matriz nativa:

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

Ou você pode simplesmente empurrar os elementos existentes em outro array:

// 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,,,,]);

Outras dicas

Simples maneiras:

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]

ou - (somente para única itens de matriz do tipo "texto")

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

ou - modo Classic: simples iteração

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]


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


Atualização - apenas mais rápido, forma legal (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;
delete temp; // discard the variable

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

Remover valores vazios

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

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]

Se você precisar remover todos os valores vazios ( "", null, indefinido e 0):

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

Para remover valores vazios e quebras de linha:

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

Exemplo:

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

retorno:

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

UPDATE (com base no comentário de Alnitak)

Em algumas situações, você pode querer manter "0" no resto da matriz e remover qualquer coisa (null, indefinido e ""), esta é uma maneira:

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

retorno:

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

Simplesmente um forro:

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

ou usando underscorejs.org :

_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]

Se você tem Javascript 1.6 ou mais tarde você pode usar Array.filter utilizando uma função de retorno return true trivial, por exemplo:

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

desde .filter ignora automaticamente elementos na matriz original faltando.

A página MDN ligada acima também contém uma boa versão do filter que pode ser usado em intérpretes de JavaScript que não suportam a versão oficial de verificação de erros.

Note que isso não irá remover as entradas null nem entradas com um valor undefined explícito, mas o OP especificamente solicitado "faltando" entradas.

Para remover buracos, você deve usar

arr.filter(() => true)
arr.flat(0) // Currently stage 3, check compatibility before using this

Para a remoção de buraco, e, Falsas (null, indefinido, 0, -0, NaN, "", falsos, document.all) valores:

arr.filter(x => x)

Para remover buraco, null, e, indefinido:

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

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

A maneira limpa para fazê-lo.

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

ES6 Simples

['a','b','',,,'w','b'].filter(v => v);

por sublinhado / Lodash:

caso de uso geral:

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

Com esvazia:

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

lodash documentação sem .

Apenas ES6 e versões mais recentes método, assumir matriz é abaixo:

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

Maneira simples:

 const clearArray = arr.filter( i => i );

Se estiver usando uma biblioteca é uma opção Eu sei underscore.js tem uma função chamada compact () http: // documentcloud.github.com/underscore/ ele também tem várias outras funções úteis relacionadas com matrizes e coleções.

Aqui está um trecho de sua documentação:

_. Compacto (array)

Retorna uma cópia da matriz com todos os valores Falsas removidos. Em JavaScript, falsa, null, 0, "", indefinido e NaN são todos Falsas.

.

_ compacto ([0, 1, falso, 2, '', 3]);

=> [1, 2, 3]

@Alnitak

Na verdade Array.filter funciona em todos os navegadores se você adicionar algum código extra. Veja abaixo.

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 é o código que você precisa adicionar para o IE, mas filtro e vale a pena programmingis funcional é imo.

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

Uma vez que ninguém mencionou isso ea maioria das pessoas têm sublinhado incluído em seu projeto, você também pode usar _.without(array, *values);.

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

Você pode achar que é mais fácil de loop sobre a matriz e construir uma nova matriz fora dos itens que você deseja manter a partir da matriz do que tentando loop e emenda como tem sido sugerido, uma vez modificar o comprimento da matriz enquanto está sendo enrolada ao longo pode apresentar problemas.

Você poderia fazer algo parecido com isto:

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

Na verdade, aqui é uma solução mais 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]

Você começa a idéia - você poderia, então, ter outros tipos de funções de filtro. Provavelmente mais do que você precisa, mas eu estava me sentindo generosa ...;)

ES6: let newArr = arr.filter(e => e);

O que sobre este (ES6):. Para remover valor Falsas de uma 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"]

Você deve usar filtro para obter array sem elementos vazios. Exemplo em ES6

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

Estou simplesmente juntar a minha voz ao acima “chamar Array..filter() do ES5 com um construtor global” golf-hack, mas eu sugiro usar Object vez de String, Boolean, ou Number como sugerido acima.

Especificamente, filter() de ES5 já não desencadear para elementos undefined no interior da matriz; assim que uma função retorna que universalmente true, que retorna todas elementos filter() hits, necessariamente só retornam elementos não undefined:

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

No entanto, escrevendo ...(function(){return true;}) é mais longo do que escrever ...(Object); eo retorno de valor do construtor Object será, sob qualquer circunstância , algum tipo de objeto. Ao contrário das primitivas-boxing-construtores sugerido acima, nenhum objeto de valor possível é Falsey, e, portanto, em um ambiente boolean, Object é um curto-mão para 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]

Quando utilizando a mais alta resposta votou acima, primeiro exemplo, eu estava ficando caracteres individuais para comprimentos de cordas superiores a 1. Abaixo está a minha solução para esse problema.

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

Em vez de não voltar se não for definido, vamos voltar se o comprimento é maior que 0. Espero que ajude alguém lá fora.

Retorna

["some string yay", "Other string yay"]
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]

O que sobre isso:

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

Isso funciona, eu testei no AppJet (você pode copiar e colar o código no seu IDE e pressione " reload" para vê-lo trabalhar, não precisa criar uma conta)

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

Outra maneira de fazer isso é tirar proveito da propriedade comprimento da matriz: embalar os itens não-nulos na 'esquerda' da matriz, em seguida, reduzir o comprimento. É um in-place algoritmo -Não aloca memória, muito ruim para o Coletor de lixo, e tem muito bom pior comportamento melhor / média / caso.

Esta solução, em comparação com outros aqui, é entre 2 a 50 vezes mais rápido no Chrome, e de 5 a 50 vezes mais rápido no Firefox, como você pode ver aqui: http://jsperf.com/remove-null-items-from-array

O código a seguir adiciona o método 'removeNull' não-enumeráveis ??para a matriz, que retorna 'isto' para-encadeamento:

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 } ) ;
foo = [0, 1, 2, "", , false, 3, "four", null]

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

retorna

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

'mau uso' do for ... in (object-membro) loop. => Apenas valores truthy aparecer no corpo do loop.

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

Isto pode ajudar você: https://lodash.com/docs/4.17.4# remover

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

Output:

Eu estou trabalhando em nodejs

Vai remover vazio elemento de matriz e exibir outro elemento.

A filtragem de entradas inválidas com uma expressão regular

array = array.filter(/\w/);
filter + regexp

A melhor maneira de remover os elementos vazios, é a utilização de Array.prototype.filter() , como já mencionado em outras respostas.

Infelizmente, Array.prototype.filter() não é suportado pelo IE <9. Se você ainda precisa de apoio IE8 ou uma versão ainda mais antiga do IE, você poderia usar o seguinte polyfill para adicionar suporte para Array.prototype.filter() nesses navegadores:

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun/*, thisArg*/) {
    'use strict';
    if (this === void 0 || this === null) {
      throw new TypeError();
    }
    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== 'function') {
      throw new TypeError();
    }
    var res = [];
    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++) {
      if (i in t) {
        var val = t[i];
        if (fun.call(thisArg, val, i, t)) {
          res.push(val);
        }
      }
    }
    return res;
  };
}

Se alguém está olhando para a limpeza de toda a matriz ou objeto esta ajuda poder .

var qwerty = {
    test1: null,
    test2: 'somestring',
    test3: 3,
    test4: {},
    test5: {
        foo: "bar"
    },
    test6: "",
    test7: undefined,
    test8: " ",
    test9: true,
    test10: [],
    test11: ["77","88"],
    test12: {
        foo: "foo",
        bar: {
            foo: "q",
            bar: {
                foo:4,
                bar:{}
            }
        },
        bob: {}
    }
}

var asdfg = [,,"", " ", "yyyy", 78, null, undefined,true, {}, {x:6}, [], [2,3,5]];

function clean_data(obj) {
    for (var key in obj) {
        // Delete null, undefined, "", " "
        if (obj[key] === null || obj[key] === undefined || obj[key] === "" || obj[key] === " ") {
            delete obj[key];
        }
        // Delete empty object
        // Note : typeof Array is also object
        if (typeof obj[key] === 'object' && Object.keys(obj[key]).length <= 0) {
            delete obj[key];
        }
        // If non empty object call function again
        if(typeof obj[key] === 'object'){
            clean_data(obj[key]);
        }
    }
    return obj;
}

var objData = clean_data(qwerty);
console.log(objData);
var arrayData = clean_data(asdfg);
console.log(arrayData);

Output:

Remove tudo o que é null, undefined, "", " ", empty object ou empty array

aqui

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top