JavaScript函数式编程:链式过滤操作如何设置默认值?
当然可以实现!针对你想要用单条链式调用完成数组filter操作、且过滤结果为空时返回指定默认值的需求,我整理了几种实用的方案,都符合函数式编程的风格:
方案一:利用concat追加默认值后取第一个元素
这种方法的思路很直观:先执行filter筛选元素,然后把默认值追加到筛选后的数组末尾,最后取数组的第一个元素。如果筛选结果不为空,第一个元素就是匹配的项;如果筛选结果为空,就会自动取到我们预设的默认值:
[1,2,3].filter(isDivisibleByTen).concat('你的默认值')[0]
⚠️ 注意:如果你的默认值本身是数组类型,记得把它放在一个数组里传入concat(比如concat(['默认数组'])),否则默认数组会被拆分成单个元素追加进去。
方案二:使用空值合并运算符??(推荐)
ES2020引入的??运算符专门用来处理null或undefined的空值场景,比传统的||更安全——它不会把0、false、''这类假值误判为空。我们可以直接取筛选后数组的第一个元素,再用??指定默认值,写法非常简洁:
[1,2,3].filter(isDivisibleByTen)[0] ?? '你的默认值'
这个方案逻辑清晰,代码量少,是我个人比较推荐的写法。
方案三:用find替代filter(更贴合单元素需求)
如果你原本的需求就是获取第一个符合条件的元素(而不是所有匹配元素组成的数组),那用find会比filter更高效——因为find找到第一个匹配项后就会停止遍历,而filter会遍历整个数组。搭配??同样可以实现空值返回默认值的效果:
[1,2,3].find(isDivisibleByTen) ?? '你的默认值'
虽然这不是严格意义上的filter操作,但如果你的场景只需要单个匹配元素,这个方案性能更优。
补充:如果需要返回默认数组而非单个元素
如果你的需求是当筛选后的整个数组为空时返回一个默认数组,而非单个元素,可以这样写:
[1,2,3].filter(isDivisibleByTen).length ? [1,2,3].filter(isDivisibleByTen) : ['默认元素1', '默认元素2']
不过这种写法会重复执行一次filter,如果数组很大的话会影响性能。如果允许稍微拆分一下(还是保持函数式风格),可以用:
const filtered = [1,2,3].filter(isDivisibleByTen); filtered.length ? filtered : ['默认元素1', '默认元素2']
内容的提问来源于stack exchange,提问作者chrisl-921fb74d

