简体   繁体   中英

Recursive JavaScript function continues to run after returning

I am trying to create a JavaScript function that recursively searches for a file/directory in a file structure and returns that file if found. This is an example of the file structure:

var fileStructure = [
  {'pictures': ['picture1.png', {'beach': ['picture2.png']}]},
  {'videos': ['video1.mov', 'video2.mov']}
]

In the dictionaries, the key represents the name of a directory and the value represents the contents of the directory. Each item in the arrays are files. So, if I called findFile('picture1.png') I should get true, or if I call findFile('videos') I should also get true. Here is what I have so far:

 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);

In my code I called this function like so: fileExists = findFile('lofi', audioLibrary); If you look at my comment surrounded by exclamation points, that line prints as expected, however even after returning true the function continues to run and, ultimately, the fileExists variables evaluates to false.

Why does the loop seem to continue even after returning?

This is what happened when I added a breakpoint to the return line. As you can see the loop runs again.

EDIT: Added the file structure that I am using.

The problem was I wasn't actually returning findFile(fileName, entry); , so the function would only search one directory, and there was no actual recursion (duh lol!) To solve this I kept track of all the sub-directories within the current directory being searched with a variable of directories . Then, once the last file in the directory being searched was checked, if no results were found, it would try searching each directory in the directories array. If it managed to find a match in any directory the function would return 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM