【问题标题】:How to filter multiple extension files using node js如何使用node js过滤多个扩展文件
【发布时间】:2021-07-03 23:04:59
【问题描述】:

我想过滤掉一些在数组中提到但不知道怎么做的文件

我看过一篇文章,但它只显示了一个扩展如何过滤它如果有一个扩展数组怎么办

async function getAllFile(folderPath, depth) {
  let files = await fs.readdir(folderPath);
  files = await Promise.all(
    files.map(async (file) => {
      const filePath = path.join(folderPath, file);
      const stats = await fs.stat(filePath);
      if (stats.isDirectory() && depth > 0) {
        return getAllFile(filePath, depth - 1);
      } else if (stats.isFile()) return filePath;
    })
  );

  return files.reduce((all, folderContents) => all.concat(folderContents), []);
}

const filenames = new Set([
".html",
".htm",
".aspx"
])

const filterFiles = async (folderPath) => {
  let filename,
    parts;
  const paths = await getAllFile(folderPath);
  
  const filteredFiles = [];
  const otherFiles = [];
  for (const filePath of paths) {
    parts = filePath.split("/");
    filename = parts[parts.length - 1];
    if (filenames.has(filename.toLowerCase())) {
      filteredFiles.push(filePath);
    } else {
      otherFiles.push(filePath);
    }
  }
  return { filteredFiles, otherFiles }; 
};

任何解决方案如何解决这个问题

【问题讨论】:

  • 没有@Cyber​​Eternal
  • 您在此处发布的代码与上面帖子中的代码完全相同,并且是我的代码。实际上,我不明白你需要什么。你也可以发布一个例子吗?比如你想在什么时候收到什么。
  • 是的,它只是您的代码,但我希望在第二个数组 OtherFiles: abc.txt, pqr.pdf 中的 FilterFiles: index.html, default.htm 中的 3 个数组中输出,但在第三个数组中,即 ignoreFIles: abc.html, pqr.aspx, xyz.htm 所有的 .html、.htm、.aspx 中没有进入 filterFile 应该进入 ignoreFile @Cyber​​Eternal
  • 请看我的回答@Praveen。

标签: javascript node.js promise callback


【解决方案1】:

您可以使用Array.filterString.lastIndexOfString.substrArray.includes获取所有匹配有效扩展名的文件

下面的方法只会返回匹配的扩展。

let files = ["abc.txt", "/test/abc.htm", "/etc/dev/xyz.html"];

const allowedExtensions = [ ".html", ".htm", ".aspx"];

const filterFiles = (files, allowedExtns) => {
  return files.filter(file => {
  //Find the last index of '.'
    const lastIndex = file.lastIndexOf(".");
    //If last index of '.' is not -1 then
    //take the substring from that index till the end and 
    //check in the allowedExnts array 
    return lastIndex !== -1 && allowedExtns.includes(file.substr(lastIndex))
  })
}

console.log(filterFiles(files, allowedExtensions));

但是,如果您希望同时获得有效和无效的,那么下面的方法会有所帮助

let files = ["abc.txt", "/test/abc.htm", "/etc/dev/xyz.html"];

const allowedExtensions = [ ".html", ".htm", ".aspx"];

const filterFiles = (files, allowedExtns) => {
  return files.reduce((acc, file) => {
    const lastIndex = file.lastIndexOf(".");
     //If last index of '.' is not -1 then
     //take the substring from that index till the end and 
     //check in the allowedExnts array & if the result is true
     //then add to `valid` array in the `acc` otherwise
     //add to `invalid` array in the `acc`
    if(lastIndex !== -1 && allowedExtns.includes(file.substr(lastIndex))) {
      acc.valid.push(file);
    } else{
      acc.invalid.push(file);
    }
    return acc;
  }, {valid: [], invalid: []})
}

console.log(filterFiles(files, allowedExtensions));

【讨论】:

  • 我想问一下我将如何在OtherFiles.push的else部分中推送return file.reduce
  • 它显示 files.reduce 不是函数@Nithish
  • 您是否将files 列表传递给filterFiles 方法?
  • 我通过使用邮递员传递 folderPath 所以基本上我用 folderPath @Nithish 替换文件
  • 但是,该函数需要一个包含所有文件名的数组。因此,您需要传递一个文件名数组,如示例所示。
【解决方案2】:

试试这个

const fs = require("fs");
const path = require("path");

const getAllFile = async (folderPath) => {
  let files = fs.readdirSync(folderPath);
  files = await Promise.all(
    files.map(async (file) => {
      const filePath = path.join(folderPath, file);
      const stats = fs.statSync(filePath);
      if (stats.isDirectory()) {
        return await getAllFile(filePath);
      } else if (stats.isFile()) return filePath;
    })
  );
  return files.reduce((all, folderContents) => all.concat(folderContents), []);
};

const fileExtensions = [
  ".html",
  ".htm",
  ".aspx",
  // Add your extensions here which you need to see in filteredFiles and don't need in otherFiles
];

const filenames = [
  "index",
  "default",
  // Add your fine names here which you need to see in filteredFiles
];

const filterFiles = async (folderPath) => {
  let filename, parts;
  const paths = await getAllFile(folderPath);
  const filteredFiles = [];
  const otherFiles = [];
  const ignoredFiles = [];
  for (const filePath of paths) {
    parts = filePath.split("/");
    filename = parts[parts.length - 1].split(".")[0];
    let splitFileName = parts[parts.length - 1].split(".");
    if (
      fileExtensions.includes(`.${splitFileName[splitFileName.length - 1]}`)
    ) {
      if (filenames.includes(filename.toLowerCase())) {
        filteredFiles.push(filePath);
      } else {
        ignoredFiles.push(filePath);
      }
    } else {
      otherFiles.push(filePath);
    }
  }
  return { filteredFiles, otherFiles, ignoredFiles };
};

filterFiles("./test")
  .then(({ filteredFiles, otherFiles, ignoredFiles }) => {
    console.log("filteredFiles:::", filteredFiles);
    console.log("otherFiles:::", otherFiles);
    console.log("ignoredFiles:::", ignoredFiles);
  })
  .catch((e) => console.log("ERRROR::", e));

【讨论】:

  • @Praveen 这是不可能的人。您是否向filenames 添加了所需的精美名称,并且还需要对fileExtensions 进行扩展? FilteredFiles 和 IgnoredFiles 条件相反,不能将同一个文件添加到它们中
  • 它的工作谢谢@Cyber​​Eternal
  • 逻辑如下。如果fileExtensions 中不存在文件扩展名,则该文件将被推送到otherFiles 列表中。否则,如果文件扩展名存在于fileExtensions,并且文件名存在于filenames,则推送到filteredFiles ,如果不存在则推送到ignoredFiles
  • 太棒了!不客气。请也为答案投票@Praveen
  • 谢谢@Praveen!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 2021-08-14
  • 2023-03-14
  • 1970-01-01
  • 2017-08-27
  • 2019-05-22
相关资源
最近更新 更多