为什么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式语法。