我正在构建一个工具,如果源代码中不再使用包含本地化字符串的 JSON 文件,该工具将清理这些文件。
首先,我将本地化文件解析为一个数组,其中包含源代码中使用(或不再使用)的所有 id,以获取正确语言的字符串值。
所以我有一个看起来像这样的数组:
const ids = ['home.title', 'home.description', 'menu.contact', 'menu.social'];
等等。你明白了。
我正在使用node.js fs promisified readFile 和 glob 来搜索 .js 源代码文件,如下所示:
const jsFiles = await globbing('./**/*.js', {cwd: directory, ignore: './**/*test.js'});
const results = jsFiles.map(async file => {
const filePath = path.join(directory, file);
return readFile(filePath, 'utf8').then((data) => {
// handle match here
}).catch(console.log);
});
我还可以使用 Ramda 来实现奇特的列表/集合功能,但没有其他库。
因此,我将能够循环 ids 数组,并为每个项目扫描整个源代码以与上面的函数匹配。但是,扫描整个源代码乘以 ids.length 似乎有点矫枉过正。 ids 数组大约有 400 个 ids,源代码是数百个大文件。
为了避免 O(M*N),有没有办法将整个数组与整个源代码进行匹配,并丢弃不匹配的数组项?或者这里的最佳实践是什么?
当前解决方案:
const cleanLocal = async () => {
const localIdList = Object.keys(await getLocalMap());
const matches = [];
localIdList.map(async id => {
const directory = path.join(__dirname, '..');
const jsFiles = await globbing('./**/*.js', {cwd: directory, ignore: './**/*test.js'});
jsFiles.map(async file => {
const filePath = path.join(directory, file);
return readFile(filePath, 'utf8').then((data) => {
if (data.indexOf(id) >= 0) {
console.log(id);
matches.push(id);
}
}).catch(console.log);
});
});
};
最佳答案
在这种情况下,您无法避免 O(M*N)
复杂性。
但是,为了提高性能,您可以切换操作顺序:首先循环文件,然后循环数组。这是因为循环文件是一个昂贵的 IO 操作,而循环数组是一个快速的内存操作。
在您的代码中,您有 M
内存操作和 M*N
IO(文件系统)操作。
如果您首先循环访问文件,您将进行 N
IO 操作和 M*N
内存操作。
关于javascript fs 在文件中搜索数组中的字符串。避免不良表现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53064508/