Unir cadenas con un delimitador solo si las cadenas no son nulas o vacías


118

Parece que debería ser simple, lo siento si me falta algo aquí, pero estoy tratando de encontrar una forma simple de concatenar solo cadenas no nulas o no vacías.

Tengo varios campos de dirección distintos:

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

Los valores para estos se establecen en función de algunos campos de formulario en la página y algún otro código js.

Quiero generar la dirección completa en a div, delimitada por coma + espacio, algo como esto:

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

El problema es que uno o todos estos campos podrían ser nulos o estar vacíos.

¿Existe alguna forma sencilla de unir todos los campos no vacíos en este grupo de campos, sin hacer una verificación de la longitud de cada uno individualmente antes de agregarlo a la cadena?


¿Por qué no tener todos esos campos en un objeto y luego repetir, comparar y descartar?
elclanrs

Respuestas:


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 es lo mismo que .filter(x => x)) elimina todos los valores "falsos" (nulos, indefinidos, cadenas vacías, etc.). Si su definición de "vacío" es diferente, deberá proporcionarla, por ejemplo:

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

solo mantendrá las cadenas no vacías en la lista.

-

(respuesta de jquery obsoleta)

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

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

117

Otra solución de una línea, que no requiere jQuery:

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

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

40
Esta es probablemente la mejor respuesta. Utiliza funciones nativas. Si está usando es6 / es2015, puede abreviarlo a [address, city, state, zip].filter(val => val).join(', ')
Sir.Nathan Stassen


13

Sólo:

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

5

La solución de @ aga es excelente, pero no funciona en navegadores más antiguos como IE8 debido a la falta de Array.prototype.filter () en sus motores JavaScript.

Para aquellos que estén interesados ​​en una solución eficiente que funcione en una amplia gama de navegadores (incluido IE 5.5 - 8) y que no requiera jQuery , consulte a continuación:

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

Incluye algunas optimizaciones de rendimiento descritas en MDN aquí .

Y aquí hay un ejemplo de uso:

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

1

Tratar

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

Demostración: violín


0
$.each([address,city,state,zip], 
    function(i,v) { 
        if(v){
             var s = (i>0 ? ", ":"") + v;
             $("#addressDiv").append(s);
        } 
    }
);`
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.