LoginSignup
4
0

More than 1 year has passed since last update.

[JavaScript] Version のソートアルゴリズムを高階関数縛りで考えてみた

Last updated at Posted at 2020-11-01

概要

  • バージョンを新規順に並べるソートアルゴリズムに憑いて、「for文を使わないと難しい」と云う声が挙がっていたので、高階関数縛りで簡単に書けるかどうかを考えてみました。

結論

  • 空行6行を含む15行ほどで書けたので、多分「かける」が正しいと思われます。

  • 所要時間は31分でした。
    バグ修正込みで40分でした。

考える元になった記事

コード

高階関数縛りのバージョン名ソートアルゴリズム
const versions = [
  '5.0.0.',
  '1.3.0.9',
  '0.2.0',
  '3.1.2',
  '5',
  '0.1.6',
  '5.0.0',
  '3.3.3.3',
  '3.3.3.3.3',
  '3.10',
  '0.2.0',
  '0.2.0a',
  '0.2.0aa',
  '0.2.0AA',
  '0.2.0Aa',
  '0.2.0aA',
  '0.2.0c',
  '0.2.0b',
  '0.2.0A',
  '0.2.0C',
  '0.2.0B',
  '0.2.0.a',
  '0.2.0.c',
  '0.2.0.b',
  '0.2.0.A',
  '0.2.0.C',
  '0.2.0.B',
  '5.0.0.',
  '5.0.0.0',
]

const output = [
  '5.0.0.0',
  '5.0.0.',
  '5.0.0.',
  '5.0.0',
  '5',
  '3.10',
  '3.3.3.3.3',
  '3.3.3.3',
  '3.1.2',
  '1.3.0.9',
  '0.2.0C',
  '0.2.0c',
  '0.2.0B',
  '0.2.0b',
  '0.2.0AA',
  '0.2.0Aa',
  '0.2.0aA',
  '0.2.0aa',
  '0.2.0A',
  '0.2.0a',
  '0.2.0.C',
  '0.2.0.c',
  '0.2.0.B',
  '0.2.0.b',
  '0.2.0.A',
  '0.2.0.a',
  '0.2.0',
  '0.2.0',
  '0.1.6',
]

const splitRegExp = /\./

/**
 * Version sort.
 * @param {string} a
 * @param {string} b
 */
function versionSort (a, b) {
  const aHash = a.split(splitRegExp)
  const bHash = b.split(splitRegExp)

  const diffIndex = aHash.findIndex((aa, i) => aa !== bHash[i])
  if (diffIndex === -1) {
    return bHash.length - aHash.length
  }

  const ax = aHash[diffIndex]
  const bx = bHash[diffIndex]

  if (!bx) {
    return -1
  }

  const na = Number(ax)
  const nb = Number(bx)

  if (isNaN(na + nb)) {
    return bx.localeCompare(ax)
  }

  return nb - na
}

const sortedVersions = versions.sort(versionSort)

console.log(
  versions,
  sortedVersions,
  sortedVersions.join() === output.join()
)
4
0
17

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0