【问题标题】:Javascript - How would you make a record unique by adding a number?Javascript - 您如何通过添加数字使记录唯一?
【发布时间】:2020-08-01 11:33:56
【问题描述】:

现在当文件已经存在时,我添加了前缀,它是文件名的时间戳以使其唯一。

但我不想使用时间戳,而是想使用序数后缀或在文件名中添加一个数字。

如果文件存在,我会在文件名中添加一个递增的数字。但我无法完全理解如何以一种好的方式做到这一点。

使用时间戳有效,但它太长了,就像我们显示文件名时一样,例如,我不想使用时间戳,而是想为文件名增加一个数字。

Hellworldfilename - 1593024232 - 时间戳太长,不是一个好主意。

它应该基于数据库中的现有记录。例如,如果我添加一个文件名为 Hellworldfilename 的文件并且它已经存在,那么新文件名将是 Hellworldfilename-1 ,如果我再次添加 Hellworldfilename ,新文件名将是 Hellworldfilename-2 等等。知道如何让文件名每次都独一无二吗?

让我举个例子。假设我在数据库中有 3 个文件名的文件

DOC
DOC-1
DOC-2

如果我添加一个文件名为 DOC 的文件,新文件名现在将是 DOC-3。

#检查文件是否存在的代码

const file = await context.service.Model.findOne({
    where: { humanId: record.id, filename: data.filename },
    paranoid: false,
  });

if (file) {
    const prefix = Date.now().toString();
    // eslint-disable-next-line no-undef
    const fileParts = data.filename.split('.');
    filename = `${fileParts[0]}-${prefix}.${fileParts[1]}`;
  

【问题讨论】:

  • 以 uuidv4 为例?
  • 问题是我在前端显示这些文件名并且看到带有长 UUID 的名称不是一个好主意。
  • 例如,如果我使用 UUID,文件名将是 Helloworldfilename-123e4567-e89b-12d3-a456-426614174000,那太长了。
  • 在数据库中写入“用户友好名称”并将文件作为 uuid 字符串存储在文件系统中。
  • 在文件名中插入数字真的很难吗?会不会更简单?

标签: javascript node.js typescript


【解决方案1】:

您需要检查文件名是否以 -somenumber 结尾。如果是这样,那么您可以提取该数字并增加它。否则将 1 放入结果中:

function getNumberedFileName(fileN) {
    //These are value initializations to cope with the situation when the file does not have a .
    var fileName = fileN;
    var fileExtension = "";
    var lastDotIndex = fileN.lastIndexOf(".");
    if ((lastDotIndex > 0) && (lastDotIndex < fileN.length - 1)) { //We are not interested in file extensions for files without an extension hidden in UNIX systems, like .gitignore and we are not interested in file extensions if the file ends with a dot
        fileName = fileN.substring(0, lastDotIndex);
        fileExtension = "." + fileN.substring(lastDotIndex + 1);
    }
    var lastDashIndex = fileName.lastIndexOf("-");
    if ((lastDashIndex > 0) && (lastDashIndex < fileName.length - 1)) {
        var lastPart = fileName.substring(lastDashIndex + 1);
        if (!isNaN(lastPart)) {
            var index = parseInt(lastPart) + 1;
            return fileName.substring(0, lastDashIndex) + "-" + index + fileExtension;
        }
    }
    return fileName + "-1" + fileExtension;
}

【讨论】:

  • 文件名是否应该基于数据库中的现有文件名?例如,假设数据库中有文件名 DOC 和 DOC-1 的现有文件,如果我再次添加文件名 DOC 的文件,它应该在添加数字之前先检查是否存在?所以根据我上面的例子,新的 DOC 现在是 DOC-2。
  • @Mr.MarkTawin 您没有提供有关您的数据库的任何信息,因此我编写了一个函数,它能够在存在文件名的情况下找到下一个文件名。如果您希望我们处理您的数据库,那么您需要展示您的数据库的外观。
  • 我已经更新了我的问题先生,也有查询数据库数据的例子,请先生检查,谢谢
  • @Mr.MarkTawin 因为我没有关于您的实际数据库的任何信息,您可以将文件名存储在具有文件名(id,文件名)结构的表中,您可以搜索 select filename from文件名按 id desc 限制 0、1 排序(假设它是 MySQL)。如果没有记录,那么您第一次使用您的文件名。如果有记录,则可以通过传递文件名来调用上面的函数。
  • 不,我的意思是我在问题上添加的查询有效,但我的问题还没有解决。
【解决方案2】:

您可以在全局范围内声明一个对象filenames,例如

const filenames={};

并使用它来跟踪已打开的文件。

下面我定义了一个函数makeUnique(),强调了我之前在这里提到的想法。事实证明我不得不稍微调整一下我的代码,但这是一个有效的 sn-p:

const makeUnique=(function(){
 const filenames={};
 return function(fn){
  const fileParts=fn.split(".");
  const prefix=filenames[fn]!=null
  ? ++filenames[fn]
  : filenames[fn]=0;
  if (prefix) fileParts[Math.max(fileParts.length-2,0)]+='-'+prefix;
  return fileParts.join('.')
 }
})();

console.log(["abc","d.e.f.c","abc","ghi","abc","abc.txt","def",
             "abc.txt","d.e.f.c","abc.txt","abc"].map(makeUnique))
.as-console-wrapper {max-height:100% !important}

我使用 IIFE 为静态对象 filenames 生成受保护范围。这现在可以通过makeUnique() 的所有调用访问,但否则是“私有的”,即。 e.不能从其他任何地方意外修改。

【讨论】:

  • +a ⁹0 是什么?
  • 您能解释一下先生这是如何解决问题的吗?>
  • 我是通过智能手机发帖的,抱歉,已修复!
  • 我假设您说的是在一个会话中多次打开文件。在这种情况下,filenames 对象将帮助您创建有意义的前缀。
  • 当我使用相同的文件名超过 3 次时,您的解决方案先生会失败。例如,如果我添加一个文件名为汽车的文件,因为没有同名的文件,所以我添加了一个文件名为汽车的文件,然后我再次添加文件名为汽车的文件,新文件名现在将是汽车-1,它工作正常,但如果我再次添加汽车这已经是一个问题了,因为它将基于汽车而不是汽车1,所以上面的算法不是汽车2,而是创建另一个汽车1
猜你喜欢
  • 2020-11-22
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 1970-01-01
相关资源
最近更新 更多