Junte strings com um delimitador apenas se as strings não forem nulas ou vazias


118

Parece que deveria ser simples, desculpe se estou perdendo algo aqui, mas estou tentando encontrar uma maneira simples de concatenar apenas strings não nulas ou não vazias.

Tenho vários campos de endereço distintos:

var address;
var city;
var state;
var zip;

Os valores para esses são definidos com base em alguns campos de formulário na página e em algum outro código js.

Quero produzir o endereço completo em a div, delimitado por vírgula + espaço, algo assim:

$("#addressDiv").append(address + ", " + city + ", " + state + ", " + zip);

O problema é que um ou todos esses campos podem ser nulos / vazios.

Existe alguma maneira simples de juntar todos os campos não vazios neste grupo de campos, sem fazer uma verificação do comprimento de cada um individualmente antes de adicioná-lo à string?


Por que não ter todos esses campos em um objeto e fazer um loop, comparar, descartar?
elclanrs

Respostas:


218

Considerar

var address = "foo";
var city;
var state = "bar";
var zip;

text = [address, city, state, zip].filter(Boolean).join(", ");
console.log(text)

.filter(Boolean)(que é o mesmo que .filter(x => x)) remove todos os valores "falsos" (nulos, indefinidos, strings vazias, etc.). Se a sua definição de "vazio" for diferente, você terá que fornecê-la, por exemplo:

 [...].filter(x => typeof x === 'string' && x.length > 0)

irá manter apenas strings não vazias na lista.

-

(resposta obsoleta do jquery)

var address = "foo";
var city;
var state = "bar";
var zip;

text = $.grep([address, city, state, zip], Boolean).join(", "); // foo, bar

117

Mais uma solução de uma linha, que não requer jQuery:

var address = "foo";
var city;
var state = "bar";
var zip;

text = [address, city, state, zip].filter(function (val) {return val;}).join(', ');

40
Esta é provavelmente a melhor resposta. Usa funções nativas. Se você estiver usando es6 / es2015, pode ser reduzido para apenas [address, city, state, zip].filter(val => val).join(', ')
Sir.Nathan Stassen,


13

Somente:

[address, city, state, zip].filter(Boolean).join(', ');

5

A solução de @aga é ótima, mas não funciona em navegadores mais antigos como o IE8 devido à falta de Array.prototype.filter () em seus mecanismos JavaScript.

Para aqueles que estão interessados ​​em uma solução eficiente trabalhando em uma ampla gama de navegadores (incluindo IE 5.5 - 8) e que não requer jQuery , veja abaixo:

var join = function (separator /*, strings */) {
    // Do not use:
    //      var args = Array.prototype.slice.call(arguments, 1);
    // since it prevents optimizations in JavaScript engines (V8 for example).
    // (See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments)
    // So we construct a new array by iterating through the arguments object
    var argsLength = arguments.length,
        strings = [];

    // Iterate through the arguments object skipping separator arg
    for (var i = 1, j = 0; i < argsLength; ++i) {
        var arg = arguments[i];

        // Filter undefineds, nulls, empty strings, 0s
        if (arg) {
            strings[j++] = arg;
        }
    }

    return strings.join(separator);
};

Inclui algumas otimizações de desempenho descritas no MDN aqui .

E aqui está um exemplo de uso:

var fullAddress = join(', ', address, city, state, zip);

1

Experimentar

function joinIfPresent(){
    return $.map(arguments, function(val){
        return val && val.length > 0 ? val : undefined;
    }).join(', ')
}
$("#addressDiv").append(joinIfPresent(address, city, state, zip));

Demo: Fiddle


0
$.each([address,city,state,zip], 
    function(i,v) { 
        if(v){
             var s = (i>0 ? ", ":"") + v;
             $("#addressDiv").append(s);
        } 
    }
);`
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.