仅当字符串不为空时,使用分隔符连接字符串

198

这感觉应该很简单,如果我漏掉了什么,请原谅,但我正在尝试找到一种简单的方法来连接仅非空字符串。

我有几个不同的地址字段:

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

这些值根据页面中的一些表单字段和其他js代码进行设置。

我想要在一个 div 中输出完整地址,用逗号+空格分隔,目标如下:

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

问题是,这些字段中的一个或全部可能为空。

有没有简单的方法将这组字段中的所有非空字段组合在一起,而无需在将其添加到字符串之前逐个检查长度?


为什么不将所有这些字段放在一个对象中,然后循环、比较、丢弃呢? - elclanrs
9个回答

446
考虑

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

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

.filter(Boolean) 将移除所有“假值”(nulls、未定义、空字符串等),等同于 .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

9
很棒!使用 filter(Boolean) 的解决方案非常优雅。 - Systems Rebooter
1
太好了!我以前从没听说过“filter”函数。 - user280109

131

另一种不需要 jQuery 的单行解决方案:

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

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

console.log(text);


49
这可能是最佳答案。使用本地函数。如果您使用es6 / es2015,则可缩短为 [address,city,state,zip] .filter(val => val).join(',') - Sir.Nathan Stassen

23

只需要:

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

1
@JD,实际上,被接受的答案先出现了(请参见历史记录中的第二次编辑)。 - HYBRID BEING
@HYBRIDBEING 你是正确的,我的好人。感谢你提醒我,我的朋友! - J D

16

Lodash 解决方案: _.filter([地址, 城市, 州, 邮编]).join()


5
@aga的解决方案非常好,但由于旧版浏览器(如IE8)中JavaScript引擎缺乏Array.prototype.filter(),因此无法使用。

对于那些想要在广泛的浏览器范围内(包括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);

3

尝试

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

Demo: Fiddle


1

2023答案

使用三元运算符的更简单解决方案

let append = `${address || ''}, ${city || ''}, ${state || ''}, ${zip || ''}`;

$("#addressDiv").append(append); 

它将评估变量是否为非假值。如果是,则返回一个空字符串。


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

0
这是一个简单的解决方案,适用于IE6(以及可能更早版本),而且没有使用filter

简短概述 → 查看代码中倒数第三个块

toString()有一个习惯,就是将数组转换为CSV并忽略所有不是字符串的内容,那么为什么不利用它呢?
["foo", null, "bar", undefined, "baz"].toString()

foo,,bar,,baz

这是一个非常方便的解决方案,适用于简单的CSV数据导出用例,因为列计数保持不变。


join() 有相同的习惯,但让你选择连接分隔符:

['We built', null, 'this city', undefined, 'on you-know-what'].join('  ')

我们在你懂的东西上建造了这座城市


由于OP要求在逗号后面有一个漂亮的空格,而且可能不喜欢额外的逗号,因此最后需要进行replace-RegEx处理:

["foo", null, "bar", undefined, "baz"].join(', ').replace(/(, ){2,}/g, ', ')

foo,bar,baz

注意: (, ){2,} 是一个相当简单的正则表达式,匹配所有出现了两次或更多次逗号后跟一个空格的情况 - 它因此具有潜在的不良副作用,即过滤掉数据开头或结尾处的任何, , ,

如果这不是问题,那么你可以使用一个整洁而简单、向后兼容的一行代码就完成了。

如果这是个问题,我们需要想出一个分隔符,它非常特殊,以至于它在你的数据项中出现两次(或一次在开头或结尾)的概率接近于零。比如,你觉得crazy-ſđ½ł⅞⅝⅜¤Ħ&Ł-delimiter怎么样?

你也可以使用任何字符,甚至是你本地字符集中不存在的字符,因为它只是我们算法的停止标志,所以你可以这样做:

["foo", null, "bar", undefined, "baz"]
  .join('emoji-✊-delimiter')
  .replace(/(emoji-✊-delimiter){2,}/g, ', ')

或者(在更DRY的版本中:

var delimiter = 'emoji-✊-delimiter'
var regEx = new RegExp('(' + delimiter + '){2,}', 'g')

["foo", null, "bar", undefined, "baz"].join(delimiter).replace(regex, ', ')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接