为什么undefined被添加到我的过滤列表?
我试图写一个节点程序,将读取文件导演,并过滤掉没有一定的文件扩展名。 (这对learnyounode来说是一个挑战)由于某种原因,它增加了“未定义”列表。 谁能告诉我为什么?
var fs = require('fs') var path = process.argv[2]; var ext = process.argv[3]; var fileList = fs.readdir(path, function callback(err, list){ if (err){ throw err; } var filteredList = list.filter(function(fileName){ var extRx = new RegExp('\.' + 'md' + '$'); return extRx.test(fileName); }); console.log(filteredList.forEach(function(val){console.log(val)})); });
输出:
ACTUAL EXPECTED "CHANGELOG.md" == "CHANGELOG.md" "LICENCE.md" == "LICENCE.md" "README.md" == "README.md" "undefined" != "" "" !=
这看起来实际上是您的控制台方法的人工产物。 您正在控制台logging过滤列表中的每个元素, 然后控制台loggingforEach函数的输出。 forEach函数没有返回值,所以它会返回外部控制台日志然后logging的'undefined'。
考虑将您的控制台日志更改为:
console.log(filteredList);
你没有包含一个可运行的例子,所以不可能告诉你什么是你没有包括的代码有问题,特别是当你甚至没有包括你想要过滤的文件的实际列表。
看到这个例子:
var list = [ "CHANGELOG.md", "LICENCE.md", "README.md", "undefined", "", ]; var filteredList = list.filter(function(fileName){ var extRx = new RegExp('\.' + 'md' + '$'); return extRx.test(fileName); }); console.log(filteredList);
这正确地过滤出你想要的值。 改变你的程序有一个console.log语句,以确保你知道什么是打印:
console.log(filteredList);
要么:
console.log(JSON.stringify(filteredList));
一个build议 – 不要太复杂:
var filteredList = list.filter(function(fileName){ var extRx = new RegExp('\.' + 'md' + '$'); return extRx.test(fileName); });
当你需要的是:
var filteredList = list.filter(name => name.match(/\.md$/));
如果你保持简单,你将不会有太多的麻烦。
更新
看完这些评论后,我发现'md'
只是一个占位符,而你正在使用真实代码中的命令行参数。 在这种情况下,我会使用escape-string-regexp
来转义string。 看到:
当你使用escape-string-regexp
:
var escape = require('escape-string-regexp');
你可以做一些事情:
var extRx = new RegExp('[.]' + escape(ext) + '$');
其中ext
是作为命令行参数获得的文件扩展名。
这里的[.]
只是我个人的喜好,在正则expression式中编写了一个字面点,我认为它更具可读性,但不会改变这里的任何行为。 逃跑更重要。
如果你不逃避string,因为你希望你的用户能够使用自定义正则expression式而不是string,那么你至less应该在try
/ catch
包装new RegExp()
调用,因为它可以抛出exception无效的正则expression式语法。