简体   繁体   English

使用 JavaScript 从数组中查找最新版本的文件名

[英]Find latest version of file name from array using JavaScript

I have string array, which contains filename with a combination of Year_Program_Version我有字符串数组,其中包含文件名和 Year_Program_Version 的组合

Ex.前任。

var fileNames = [
  "2021_Test_V1",
  "2021_Test_V2",
  "2021_Test_V4",
  "2021_Test_V3",
  "2020_Test_V11",
  "2020_Test_V10"
];

Looking for output array having: 2021_Test_V4, 2020_Test_V11寻找具有:2021_Test_V4、2020_Test_V11 的输出数组

Build an object with all the year/programs as keys and their latest version as values, then map back to an array of file names:以所有年份/程序为键,以它们的最新版本为值构建一个对象,然后映射回文件名数组:

 const fileNames = [ "2021_Test_V1", "2021_Test_V2", "2021_Test_V4", "2021_Test_V3", "2020_Test_V11", "2020_Test_V10" ]; const latestFileNames = Object.entries(fileNames.reduce((a, v) => { const [yp, version] = v.split(/_V(?=\\d+$)/); a[yp] = a[yp] && +a[yp] >= +version ? a[yp] : version; return a; }, {})).map(([yp, version]) => `${yp}_V${version}`); console.log(latestFileNames)

A slightly different solution, working off the following assumptions.一个稍微不同的解决方案,解决以下假设。

Assumptions:假设:

  • format is fixed and delimited by underscore (underscore isn't used in the year / program / version).格式固定并由下划线分隔(年份/程序/版本中不使用下划线)。
  • sorting by version ascending (OP wants the largest version).按版本升序排序(OP 想要最大的版本)。
  • version is numeric (excluding preceding "V" and has no leading zeros).版本是数字(不包括前面的“V”并且没有前导零)。
  • code does not rely on fileNames sorting.代码不依赖于fileNames排序。

Explanation:解释:

  1. parse the string to get year / program / version (numeric)解析字符串以获取年份/程序/版本(数字)
  2. check if an existing value exists for "<year>_<program>"检查“<year>_<program>”是否存在现有值
    1. if value doesn't exist, then this is the latest version.如果值不存在,则这是最新版本。
    2. if value does exist, check if this version is larger than the existing version.如果值确实存在,请检查此版本是否大于现有版本。

code.js代码.js

 var fileNames = [ "2021_Test_V1", "2021_Test_V2", "2020_Test_V11", "2021_Test_V4", "2021_Test_V3", "2020_Test_V10" ] /* get latest version (grouped) by year + program */ const latestVersion = fileNames.reduce((accu, curr) => { let [year, program, version] = curr.split('_') version = parseInt(version.substring(1)) const key = `${year}_${program}` const prevVersion = accu[key] if (typeof prevVersion === 'undefined' || version > prevVersion) accu[key] = version return accu }, {}) // convert back to array of filenames... console.log(Object.keys(latestVersion).map(k => `${k}_V${latestVersion[k]}`))

Returns: ["2021_Test_V4", "2020_Test_V11"]返回: ["2021_Test_V4", "2020_Test_V11"]

I'd start by creating a map holding the filename prefixes and the latest version (numerically).我首先创建一个包含文件名前缀和最新版本(数字)的映射。

You can then map those entries back into their complete filenames.然后,您可以将这些条目映射回其完整的文件名。

For example例如

 const fileNames = [ "2021_Test_V1", "2021_Test_V2", "2021_Test_V4", "2021_Test_V3", "2020_Test_V11", "2020_Test_V10" ] const fnRegex = /(.+)_V(\\d+)$/ const versionMap = fileNames.reduce((map, fn) => { let [_, prefix, version] = fn.match(fnRegex) let maxVersion = Math.max(version, map.get(prefix) || 0) return map.set(prefix, maxVersion) }, new Map()) const latestVersions = Array.from(versionMap, ([prefix, version]) => `${prefix}_V${version}`) console.info(latestVersions)

One possible solution (maybe not so good in performance) is to use Array.filter() with a nested Array.some() to keep only the elements meeting the expected condition.一种可能的解决方案(性能可能不太好)是将Array.filter()与嵌套的Array.some()一起使用,以仅保留满足预期条件的元素。 This also assumes that all years uses the four digit format.这也假设所有年份都使用四位数格式。

 var fileNames = [ "2021_Test_V1", "2021_Test_V2", "2021_Test_V4", "2021_Test_V3", "2021_Test_V10", "2020_Test_V11", "2020_Test_V10", "2019_Test_V1" ]; let res = fileNames.filter((str, i, arr) => { let [year, app, version] = str.split("_"); return !arr.some(s => { let [y, a, v] = s.split("_"); return y === year && +v.slice(1) > +version.slice(1); }); }); console.log(res);
 .as-console {background-color:black !important; color:lime;} .as-console-wrapper {max-height:100% !important; top:0;}

Based on Robby Cornelissen answer, but for ECMASCRIPT3, I known it's old, but it's, as far as I known, the only version that's Adobe Animate CC 2019 JS programming API understand :-(.基于Robby Cornelissen 的回答,但对于 ECMASCRIPT3,我知道它很旧,但据我所知,它是 Adob​​e Animate CC 2019 JS 编程 API 理解的唯一版本:-(。

With the help of Closure:在 Closure 的帮助下:

java -jar closure-compiler\closure-compiler-v20200406.jar --language_in ECMASCRIPT_2015 --language_in ECMASCRIPT3 --js test.js --js_output_file test_es3.js --compilation_level BUNDLE

Result code:结果代码:

var fileNames = [
  "2021_Test_V1",
  "2021_Test_V2",
  "2021_Test_V4",
  "2021_Test_V3",`enter code here`
  "2020_Test_V11",
  "2020_Test_V10"
];

function e(a) {
  var b = 0;
  return function() {
    return b < a.length ? {done:!1, value:a[b++]} : {done:!0};
  };
}

function f(a) {
  var b = "undefined" != typeof Symbol && Symbol.iterator && a[Symbol.iterator];
  return b ? b.call(a) : {next:e(a)};
}

// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
  Object.keys = (function() {
    'use strict';
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function(obj) {
      if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) {
        throw new TypeError('Object.keys called on non-object');
      }

      var result = [], prop, i;

      for (prop in obj) {
        if (hasOwnProperty.call(obj, prop)) {
          result.push(prop);
        }
      }

      if (hasDontEnumBug) {
        for (i = 0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) {
            result.push(dontEnums[i]);
          }
        }
      }
      return result;
    };
  }());
}

Array.prototype.getLastVersion = function(){
    var filenames = this.toString();
    var g = Object.entries(filenames.split(",").reduce(function(a, b) {
        var c = f(b.split(/_V(?=\d+$)/)), d = c.next().value;
        c = c.next().value;
        a[d] = a[d] && +a[d] >= +c ? a[d] : c;
        return a;
    }, {})).map(function(a) {
        var b = f(a);
        a = b.next().value;
        b = b.next().value;
        return a + "_V" + b;
    });
    return g;
}

console.log(fileNames.getLastVersion());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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