我正在尝试创建一个JavaScript函数,该函数以递归方式搜索文件结构中的文件/目录,并在找到该文件时返回该文件。这是文件结构的示例:
var fileStructure = [
{'pictures': ['picture1.png', {'beach': ['picture2.png']}]},
{'videos': ['video1.mov', 'video2.mov']}
]
在词典中,键代表目录的名称,而值代表目录的内容。数组中的每个项目都是文件。因此,如果我打电话给findFile('picture1.png')
,我应该成为现实;或者,如果我打电话给findFile('videos')
,我也应该成为真实。这是我到目前为止的内容:
var fileStructure = [{ "music": [{ "acoustic": ["vlad-gluschenko-stars-extended.mp3"] }, { "chinese": ["AlbumArtSmall.jpg", "Folder.jpg", "keys-of-moon-yugen.mp3"] }, { "lofi": ["le-gang-relax-man.mp3", "purple-cat-field-of-fireflies.mp3"] }] }, { "sounds": [{ "campfire": ["fire-crackle.mp3", "fire-rumble.mp3"] }, { "rain": ["rain-heavy.mp3", "rain-light.mp3", "rain-tapping.mp3"] }, { "thunderstorm": ["thunderstorm.mp3"] }, { "wind": ["wind-base.mp3", "wind-howling.mp3", "wind-rattling.mp3"] }] }]
function findFile(fileName, dir) {
for (i in dir) {
let entry = dir[i];
// If entry is a dictionary, unpack into array
if (entry.constructor == Object) {
// If the file being searched for is itself a directory
if (Object.keys(entry).indexOf(fileName) != -1) {
// !!!!! THIS PRINTS BUT THE FUNCTION KEEPS RUNNING !!!!!
console.log(`Found directory: ${fileName}`);
return true;
}
entry = Object.values(entry);
}
// If entry is an array (meaning it is the contents of a directory)
if (Array.isArray(entry)) {
findFile(fileName, entry);
}
// Found file
else if (entry == fileName) {
return true;
}
}
return false;
}
//
fileExists = findFile('tets', fileStructure);
console.log("done", fileExists);
fileExists = findFile('lofi', fileStructure);
console.log("done", fileExists);
在我的代码中,我这样调用该函数:fileExists = findFile('lofi', audioLibrary);
如果您在注释中用感叹号包围,则该行将按预期方式打印,但是即使返回true后,该函数仍会继续运行,最终, fileExists变量的计算结果为false。
为什么即使返回后循环仍会继续?
This是我在返回行中添加断点时发生的情况。如您所见,循环再次运行。
编辑: 添加了我正在使用的文件结构。
答案 0 :(得分:0)
问题是我实际上没有返回findFile(fileName, entry);
,所以该函数将仅搜索一个目录,并且没有实际的递归(哈哈!)为了解决这个问题,我跟踪了所有子目录在当前目录中使用变量directories
搜索。然后,一旦检查了要搜索的目录中的最后一个文件,如果没有找到结果,它将尝试搜索directories
数组中的每个目录。如果它设法在任何目录中找到匹配项,则该函数将返回true。
fileStructure = [{ "music": [{ "acoustic": ["vlad-gluschenko-stars-extended.mp3"] }, { "chinese": ["AlbumArtSmall.jpg", "Folder.jpg", "keys-of-moon-yugen.mp3"] }, { "lofi": ["le-gang-relax-man.mp3", "purple-cat-field-of-fireflies.mp3"] }] }, { "sounds": [{ "campfire": ["fire-crackle.mp3", "fire-rumble.mp3"] }, { "rain": ["rain-heavy.mp3", "rain-light.mp3", "rain-tapping.mp3"] }, { "thunderstorm": ["thunderstorm.mp3"] }, { "wind": ["wind-base.mp3", "wind-howling.mp3", "wind-rattling.mp3"] }] }]
function findFile(fileName, dir) {
var directories = [];
for (i in dir) {
let entry = dir[i];
// If entry is a dictionary, unpack into array
if (entry.constructor == Object) {
// If the file being searched for is itself a directory, then search the dictionary for a directory with the name of fileName
if (Object.keys(entry).indexOf(fileName) != -1) {
return true;
}
entry = Object.values(entry);
}
// If entry is an array (meaning it is the inside of a directory)
if (Array.isArray(entry)) {
directories.push(entry);
}
else if (entry == fileName) {
console.log('Found the file:');
console.log(entry);
return entry;
}
// If item is the last item in directory and no files have matched, begin to search each of the sub-directories
if (i == dir.length - 1) {
for (directory of directories) {
if (findFile(fileName, directory)) {
return true;
}
}
}
}
return false;
}
fileExists = findFile('foo', fileStructure);
console.log('done', fileExists);
fileExists = findFile('lofi', fileStructure);
console.log('done', fileExists);