Joindre les chaînes avec un délimiteur uniquement si les chaînes ne sont pas nulles ou vides

118

Cela donne l'impression que cela devrait être simple, donc désolé s'il me manque quelque chose ici, mais j'essaie de trouver un moyen simple de concaténer uniquement des chaînes non nulles ou non vides.

J'ai plusieurs champs d'adresse distincts:

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

Les valeurs de ceux-ci sont définies en fonction de certains champs de formulaire de la page et d'un autre code js.

Je veux afficher l'adresse complète dans un div, délimité par une virgule + espace, donc quelque chose comme ceci:

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

Le problème est qu'un ou tous ces champs peuvent être nuls / vides.

Existe-t-il un moyen simple de joindre tous les champs non vides de ce groupe de champs, sans vérifier la longueur de chacun individuellement avant de l'ajouter à la chaîne?

froadie
la source
Pourquoi ne pas avoir tous ces champs dans un objet puis boucler, comparer, ignorer?
elclanrs

Réponses:

218

Considérer

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

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

.filter(Boolean)(qui est le même que .filter(x => x)) supprime toutes les valeurs "fausses" (nulles, non définies, chaînes vides, etc.). Si votre définition de "vide" est différente, vous devrez la fournir, par exemple:

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

ne conservera que les chaînes non vides dans la liste.

-

(réponse jquery obsolète)

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

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

Encore une autre solution en une ligne, qui ne nécessite pas jQuery:

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

text = [address, city, state, zip].filter(function (val) {return val;}).join(', ');
aga
la source
40
C'est probablement la meilleure réponse. Utilise des fonctions natives. Si vous utilisez es6 / es2015, il peut être raccourci à juste [address, city, state, zip].filter(val => val).join(', ')
Monsieur Nathan Stassen
14

Solution Lodash :_.filter([address, city, state, zip]).join()

Tim Santeford
la source
13

Juste:

[address, city, state, zip].filter(Boolean).join(', ');
tikhpavel
la source
5

La solution de @ aga est excellente, mais elle ne fonctionne pas dans les anciens navigateurs comme IE8 en raison du manque de Array.prototype.filter () dans leurs moteurs JavaScript.

Pour ceux qui sont intéressés par une solution efficace fonctionnant dans un large éventail de navigateurs (y compris IE 5.5 - 8) et qui ne nécessite pas jQuery , voir ci-dessous:

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

Il inclut quelques optimisations de performances décrites sur MDN ici .

Et voici un exemple d'utilisation:

var fullAddress = join(', ', address, city, state, zip);
Alexandre Abakumov
la source
1

Essayer

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

Démo: Fiddle

Arun P Johny
la source
0
$.each([address,city,state,zip], 
    function(i,v) { 
        if(v){
             var s = (i>0 ? ", ":"") + v;
             $("#addressDiv").append(s);
        } 
    }
);`
nicb
la source