Home > Software design >  How do I get only the elements from an array that end with "x" or "y"?
How do I get only the elements from an array that end with "x" or "y"?

Time:04-13

I have a function that recursively searches a directory for files and returns them as an array. I only want files that end with ".js" or ".ts". For that, I'm trying to use Array.filter(). However, it looks as if this would not work, since only files ending in ".js" are returned. How can I filter only the files ending in ".js" or ".ts"?

function getFiles(dir: string): string[] {
    let files: string[] = [];
    fs.readdirSync(dir).forEach((file) => {
        if (fs.statSync(path.join(dir, file)).isDirectory()) {
            files = files.concat(getFiles(path.join(dir, file)));
        } else {
            files.push(path.join(dir, file));
        }
    });
    return files;
}

const files = getFiles(path.join(__dirname, "xyz")).filter((file) => file.endsWith(".js" || ".ts"));

CodePudding user response:

Why don't use just use an existing package, like rrdir?

That takes care of matching (and excluding). It also deals with errors, and whether or not symlinks should be followed.

Then it's as easy as

const rrdir = require("rrdir");
const opts  = { include: [ '**/*.{js,ts}' ] };

for await ( const entry of rrdir( 'path/to/root' , opts ) ) {
  // => { path: 'path/to/root/. . ./file', directory: false, symlink: false }
}

Or if you're willing to wait for the entire tree be be collected before getting anything back:

const rrdir = require('rrdir');
const opts  = { include: [ '**/*.{js,ts}' ] };
const files = rrdir.sync( 'path/to/root', opts ) ;

CodePudding user response:

".js" || ".ts" evaluates to .js. Unfortunately you can't pass a condition like this. Try running ".js" || ".ts" in a browser console to see.

This would be the correct version:

const files = getFiles(path.join(__dirname, "xyz"))
  .filter(file => file.endsWith(".js") || file.endsWith(".ts"));

Alternatively:

const files = getFiles(path.join(__dirname, "xyz"))
  .filter(file => file.match(/(j|t)s$/);
  • Related