【问题标题】:Parsing a version number string to an associating value将版本号字符串解析为关联值
【发布时间】:2021-11-01 12:26:14
【问题描述】:

我正在尝试解析版本字符串(下面的示例),以便根据与下面列出的以下规则匹配的键返回一个值。

每个版本 ID 都可以包含通配符,但输入不能。当然,这个对象是动态的,很可能会包含更多的版本匹配。

在本例中,版本字符串将为“1.2.3”。

  • 高于 3.2.1 的版本 ID 将返回“null”
  • 3.2.1 和 2.8.10 之间的版本 ID 将返回“testing_server”
  • 2.8.10 的版本 ID 将返回“second_value”
  • 2.8.10 和 1.0.* 之间的版本 ID 将返回“最后一个值”
  • 匹配 1.0.* 或更低(包括 0.*)的版本 ID 将返回“最后一个值”

示例对象:

{
   "3.2.1": "testing_server",
   "2.8.10": "second_value",
   "1.0.*": "last value"
}

我已经尝试了几个函数,每个函数都包括正则表达式或手动比较,但运气不佳。我知道这有点困难,但希望有人能提供帮助。 :)

【问题讨论】:

  • 这里没有 JSON。它是一个 POJO(普通的旧 JavaScript 对象)——JSON 是一个对象的字符串表示
  • const version = Object.keys(obj).map(key => { const versions = key.split("."); if (...) return "testing_server"; else if (....) return "second value""; return "error" }) ...
  • 我真的不想返回静态值,即使在这种情况下,因为函数需要依赖可能的版本通配符、额外数字等。对象不会相同每次都与版本字符串相同。所以它需要在某种程度上是动态的。
  • 我不明白你的评论。在您想要返回静态值而现在不返回的问题中?
  • 基本上,对象和它返回的值每次都会不同,因为我必须在大约 40 个不同的“配置”上运行它,你可以调用它们。版本字符串也有所不同,并且不会每次都相同。所以它可能最终使用“3.2.1”作为版本字符串,然后使用“2.3.*”作为另一个版本字符串,以及将遵循相同结构的对齐配置,只是不会包含相同的值。希望这可以更好地清除它:)

标签: javascript node.js versioning


【解决方案1】:

这是一个开始。

const versions = {
  "4": null,
  "3.2.1": "testing_server",
  "2.8.10": "second_value",
  "1.0.*": "last value"
}

const maxLength = 3
const getLiteral = (versions,version) => {
  return Object.entries(versions).filter(([key,val]) => {
    const parts = key.split(".").map(part => part.padStart(maxLength,"0")).join(".")
    const vparts = version.split(".").map(part => part.padStart(maxLength,"0")).join(".")
    console.log(vparts,parts,vparts > parts)
    return vparts > parts
  }).flat()[1] || null
};


let verText = getLiteral(versions,"1.2.3")
console.log(verText)
verText = getLiteral(versions,"4.2.3")
console.log(verText)

【讨论】:

  • 干杯,我明天会试一试,并从那里扩展它。 :)
【解决方案2】:

我会使用这样的函数来使版本字符串具有可比性:

function comparableValue(versionString) {
  const digits = versionString.split(".");
  digits.reverse();
  let value = 0;
  for (let i = 0; i < digits.length; i++) {
   value += Math.pow(1000, i) * digits[i];
  }
  return value;
}

function classify(wildcard, value) {
  const boundaries = {
    "3.2.1": "testing_server",
    "2.8.10": "second_value",
  };
  const lowestBoundary = `1.0.${wildcard}`;
  boundaries[lowestBoundary] = "last_value";
  const keys = Object.keys(boundaries);
  keys.sort(function(a, b) {
    return comparableValue(a) - comparableValue(b);
  });
  for (const key of keys) {
    if (comparableValue(value) < comparableValue(key)) {
      return boundaries[key];
    }
  }
  return null;

}

const examples = [
  "3.5.5",
  "3.1.1",
  "2.10.10",
  "2.8.8",
  "1.1.1",
  "0.4.2",
];


const answers = {};

for (const example of examples) {
  answers[example] = classify(3, example);
}

console.log(answers);

将每个 1.1.1 风格的版本转换为可比较的价值,使每个数字的价值是右侧数字的 1000 倍。由于数字永远不会达到 1000,因此它应该始终有效。 800 或 258 也可以,但打印出可比较的数字会使调试变得更加困难。

然后,如果我理解正确,我会让排序函数将通配符的值作为参数。

【讨论】:

    【解决方案3】:

    我最终使用了“compare-versions”以及一些逻辑来实现它。

    const compareVersions = require('compare-versions');
    
    function getVersion(version) {
        const versions = {
            "3.2.1": "testing_server",
            "2.8.10": "second_value",
            "1.0.*": "last value"
        }
        const sortedKeys = Object.keys(versions).sort(compareVersions);
    
        // not required
        //if (compareVersions(version, sortedKeys[sortedKeys.length - 1]) > 0) return null;
    
        let i = 0;
        while (i < sortedKeys.length && compareVersions(version, sortedKeys[i]) > 0) i++;
        return versions[sortedKeys[i]] || null;
    }
    
    const examples = [
        "3.2.2",
        "3.2.1",
        "2.8.11",
        "2.8.10",
        "1.1.0",
        "1.0",
        "0.0"
    ];
    
    const answers = {};
    for (const example of examples) {
        answers[example] = getVersion(example);
    }
    console.log(answers);
    

    【讨论】:

      猜你喜欢
      • 2023-01-24
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 2021-02-10
      相关资源
      最近更新 更多