Łącz ciągi za pomocą separatora tylko wtedy, gdy ciągi nie są puste ani puste


118

Wydaje się, że powinno to być proste, więc przepraszam, jeśli czegoś tutaj brakuje, ale próbuję znaleźć prosty sposób łączenia tylko niezerowych lub niepustych ciągów.

Mam kilka różnych pól adresowych:

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

Wartości tych są ustawiane na podstawie niektórych pól formularza na stronie i innego kodu js.

Chcę wypisać pełny adres w div, oddzielony przecinkiem + spacja, więc coś takiego:

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

Problem polega na tym, że jedno lub wszystkie z tych pól mogą być puste / puste.

Czy istnieje prosty sposób na połączenie wszystkich niepustych pól w tej grupie pól bez sprawdzania długości każdego z nich z osobna przed dodaniem go do ciągu?


Dlaczego nie mieć wszystkich tych pól w obiekcie, a następnie zapętlić, porównać, odrzucić?
elclanrs

Odpowiedzi:


218

Rozważać

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

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

.filter(Boolean)(czyli to samo co .filter(x => x)) usuwa wszystkie „fałszywe” wartości (wartości null, undefined, puste łańcuchy itp.). Jeśli Twoja definicja „pustego” jest inna, musisz ją podać, na przykład:

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

zachowa na liście tylko niepuste ciągi.

-

(przestarzała odpowiedź w jquery)

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

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

117

Kolejne jednoliniowe rozwiązanie, które nie wymaga jQuery:

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

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

40
To chyba najlepsza odpowiedź. Używa funkcji natywnych. Jeśli używasz es6 / es2015, można go skrócić do samego [address, city, state, zip].filter(val => val).join(', ')
Sir Nathan Stassen



5

Rozwiązanie @ aga jest świetne, ale nie działa w starszych przeglądarkach, takich jak IE8 z powodu braku Array.prototype.filter () w ich silnikach JavaScript.

Dla zainteresowanych wydajnym rozwiązaniem działającym w szerokiej gamie przeglądarek (w tym IE 5.5 - 8), które nie wymaga jQuery , zobacz poniżej:

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

Zawiera kilka optymalizacji wydajności opisanych w MDN tutaj .

A oto przykład użycia:

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

1

Próbować

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);
        } 
    }
);`
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.