Об'єднуйте рядки з роздільником лише тоді, коли рядки не є нульовими або порожніми


118

Це здається, що це повинно бути просто, так що вибачте, якщо я щось тут пропускаю, але я намагаюся знайти простий спосіб об'єднати лише ненулі або непусті рядки.

У мене є кілька різних адресних полів:

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

Значення для них встановлюються на основі деяких форм форм сторінки та деяких інших js-кодів.

Я хочу вивести повну адресу в divрозділеному комою + пробілом, так що:

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

Проблема в тому, що одне або всі ці поля можуть бути нульовими / порожніми.

Чи є якийсь простий спосіб приєднати всі непорожні поля до цієї групи полів, не роблячи перевірки довжини кожного окремо перед тим, як додати його до рядка?


Чому б не всі ці поля в об'єкті потім циклічно, порівняти, відкинути?
elclanrs

Відповіді:


218

Розглянемо

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

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

.filter(Boolean)(що таке саме .filter(x => x)) видаляє всі "хибні" значення (нулі, невизначені, порожні рядки тощо). Якщо ваше визначення "порожній" інше, вам доведеться вказати його, наприклад:

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

збереже в списку лише непусті рядки.

-

(застаріла відповідь jquery)

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

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

117

Ще одне лінійне рішення, яке не потребує jQuery:

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

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

40
Це, мабуть, найкраща відповідь. Використовує нативні функції. Якщо ви використовуєте es6 / es2015, це може бути скорочено до просто [address, city, state, zip].filter(val => val).join(', ')
сер.Натан Стассен



5

Рішення @ aga чудово, але воно не працює в старих браузерах, таких як IE8 через відсутність Array.prototype.filter () у своїх двигунах JavaScript.

Для тих, хто зацікавлений в ефективному рішенні, що працює в широкому діапазоні браузерів (включаючи IE 5.5 - 8) і не потребує jQuery , див. Нижче:

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

Він включає деякі оптимізації продуктивності, описані тут на MDN .

Ось приклад використання:

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

1

Спробуйте

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

Демо: Fiddle


0
$.each([address,city,state,zip], 
    function(i,v) { 
        if(v){
             var s = (i>0 ? ", ":"") + v;
             $("#addressDiv").append(s);
        } 
    }
);`
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.