热搜:fiddler git ip ios 代理
历史搜索

如何找到版本列表中的最新版本号?

游客2024-09-08 12:33:01
目录文章目录
  1. 问题
  2. 怎么解决?
  3. 巧妙的方式呢?

问题

需要前端从接口返回的版本号列表中,找出最大的版本号。

比如接口返回的版本列表是:

['6.11', '6.11.03', '6.11.03', '6.11.06', '6.11.05', '6.11.07', '6.11.09', '6.12', '6.11.12']

那前端找到的最大版本号是 6.12。

怎么解决?

这里有个问题,一般的版本号主要分为主版本,次版本以及补丁版本。

但这里的版本号是数据库内核版本,所以不一定完全是上面讲的只有三个版本。

有可能是多个分割的数字,比如四个,甚至五个。比如 oracle 的版本号:11.1.0.6.0。

如何通过 js 实现获取到最大的版本号?

很明显,是不能直接把数字之间的点去掉,然后相加对比大小。

因为涉及到补 0 和进位的问题,会比较麻烦。

但从 js 的角度,有一个简单粗暴的方式:

就是可以利用 js 动态语言的特性,把版本号列表都存到对象里面,然后逐一判断,把不符合条件的对象都删掉,剩下的自然就是最大的版本号了。

来段代码练练手:

const data = ['6.11', '6.11.03', '6.11.03', '6.11.06', '6.11.05', '6.11.07', '6.11.09', '6.12', '6.11.12']

function getMaxVersion(data) {
  // 先把版本信息整理成对象,对象的值是各个版本号组成的数组。比如 6.11,则 versionObj['6.11'] = ['6', '11']
  const versionObj = {}
  // 同时计算对象值数组的长度,下面遍历要以最大长度来循环
  let maxLength = 0
  for (let i = 0; i < data.length; i++) {
    versionObj[data[i]] = []
    let length = 0
    data[i].split('.').forEach((element) => {
      length++
      versionObj[data[i]].push(element)
    })
    if (length > maxLength) {
      maxLength = length
    }
  }
  let maxValue = null
  // 把对象的值每一个数组项都对比判断,得出当前数组项的最大值,然后把小于最大值的对象都删了,剩下的便是最大值的对象了
  // 比如 versionObj['6.11.03'] = ['6', '11', '03'],则判断 6,然后再判断 11,,然后再判断 03,以此类推。
  for (let j = 0; j < maxLength; j++) {
    for (let option in versionObj) {
      // maxValue 第一次肯定是 null,此时把第一个对象的值默认为 maxValue
      if (maxValue === null) {
       // 对象的值在对应的数组中可能没有,也就是 undefined,那就需要给个 0,好对比判断
        maxValue = versionObj[option][j] ? versionObj[option][j] : 0
      } else {
        // 然后跟其他的值对比,如果大于 maxValue,则赋值给 maxValue。以便当前循环结束后,maxValue 就是最大值
        if ((versionObj[option][j] ? versionObj[option][j] : 0) > maxValue) {
          maxValue = versionObj[option][j] ? versionObj[option][j] : 0
        }
      }
    }
    // 然后再循环判断,把所有小于 maxValue 的对象都删了,剩下的便是最大值的对象了
    for (let option in versionObj) {
      if ((versionObj[option][j] ? versionObj[option][j] : 0) < maxValue) {
        delete versionObj[option]
      }
    }
    // 每次循环结束都重置为 null,保证新的循环开始的第一次都是 null
    maxValue = null
  }
  let result = []
  for (let option in versionObj) {
    // 对象仅剩一个值了,直接取就可以
    result = versionObj[option]
  }
  // 如果 result 没有值,则取版本列表的第一个
  return result.join('.') ? result.join('.') : data[0]
}

console.log(getMaxVersion(data))
// 6.12

虽然上述代码可以实现效果。

但是,是不是觉得有点不够优雅?是不是觉得复杂繁琐了?

巧妙的方式呢?

不要老想着怎么对版本号进行分割、拼接甚至比较判断。

其实可以换个思路:

比如先排序,然后直接获取排序后的第一个值,不就是可以巧妙的获取到最大的版本号了吗?

代码如下:

const data = ['6.11', '6.11.03', '6.11.03', '6.11.06', '6.11.05', '6.11.07', '6.11.09', '6.12', '6.11.12'];  

function sortVersion(data) {
  const result = data.sort(function (a, b) {
    // 先分割为数组
    let aParts = a.split('.')
    let bParts = b.split('.')
    
    const len = Math.max(aParts.length, bParts.length)
    // 然后再比较当前数组的所有部分,直到找到不同的部分或者数组末尾
    for (let i = 0; i < len; i++) {
      let aNext = i < aParts.length ? parseInt(aParts[i]) : 0
      let bNext = i < bParts.length ? parseInt(bParts[i]) : 0      
      if (aNext < bNext) { // 降序排列 return 1 } if (aNext > bNext) {
        return -1
      }
    }
    // 如果都相同,则返回 0,表示两个版本号相等
    return 0
  })
  return result
}

console.log(sortVersion(data)[0]
标签:JavaScript