Объединяйте строки с разделителем, только если строки не являются нулевыми или пустыми

118

Кажется, это должно быть просто, извините, если мне что-то здесь не хватает, но я пытаюсь найти простой способ объединить только ненулевые или непустые строки.

У меня есть несколько разных адресных полей:

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

Значения для них устанавливаются на основе некоторых полей формы на странице и некоторого другого кода js.

Я хочу вывести полный адрес в виде a 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
georg
источник
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(', ')
сэр Натан Стассен,
14

Решение Lodash :_.filter([address, city, state, zip]).join()

Тим Сэнтефорд
источник
13

Просто:

[address, city, state, zip].filter(Boolean).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);
        } 
    }
);`
никб
источник