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

这看起来应该很简单,如果我在这里遗漏了什么,那么很抱歉,但是我正在尝试找到一种简单的方法来连接非空字符串或非空字符串。

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

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

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

我想在 div中输出完整的地址,用逗号 + 空格分隔,所以类似这样:

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

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

有没有什么简单的方法可以联接这组字段中的所有非空字段,而不必在将每个字段添加到字符串之前单独检查它们的长度?

123458 次浏览

试试看

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

演示: 小提琴

考虑一下

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

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

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


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

@ aga 的解决方案 很不错,但是由于 JavaScript 引擎中缺少 Filter (),它在 IE8这样的老式浏览器中无法工作。

一个可以在多种浏览器(包括 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);

只要:

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

下面是一个简单的、 IE6(可能更早)向后兼容的解决方案,没有 filter

TL; DR →查看最后一段代码

toString()习惯于将数组转换为 CSV 并忽略非字符串的所有内容,那么为什么不利用这一点呢?

["foo", null, "bar", undefined, "baz"].toString()

foo,,bar,,baz

对于直接的 CSV 数据导出用例来说,这是一个非常方便的解决方案,因为列计数保持不变。


join()有相同的习惯,但让我们选择加入分隔符:

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

We built 🤘🏼 🤘🏼 this city 🤘🏼 🤘🏼 on you-know-what


因为 OP 要求在逗号后面加一个漂亮的空格,而且可能不喜欢多加一个逗号,所以他们在结尾处加了一个 replace-RegEx:

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

foo, bar, baz

注意: (, ){2,}是一个相当简单的正则表达式,它匹配所有2 + 逗号后跟一个空格的出现——因此它有潜在的不良副作用,过滤任何 , , , 出现在你的数据的开始或结束。

不用担心,这里已经完成了一个整洁、简单、向后兼容的一行程序。

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

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

["foo", null, "bar", undefined, "baz"]
.join('emoji-✊🏻🙈🕺🤷🏼🧘🏽🎸🏆🚀-delimiter')
.replace(/(emoji-✊🏻🙈🕺🤷🏼🧘🏽🎸🏆🚀-delimiter){2,}/g, ', ')

或(在更多的 干的版本中:

var delimiter = 'emoji-✊🏻🙈🕺🤷🏼🧘🏽🎸🏆🚀-delimiter'
var regEx = new RegExp('(' + delimiter + '){2,}', 'g')


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