在Javascript中对版本点数字符串进行排序? [英] Sort version-dotted number strings in Javascript?

查看:122
本文介绍了在Javascript中对版本点数字符串进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列以下字符串:

  ['5.5.1','4.21.0','4.22 .0','6.1.0','5.1.0','4.5.0'] 

...等。



我需要一个能够给我以下订购结果的解决方案

  ['4.5.0','4.21.0','4.22.0','5.1.0','5.5.1','6.1.0']。 

我试图实现排序,因此它首先按照第一个位置的数字进行排序,而不是大小写等式,按第二个位置的数字排序(在第一个点之后),依此类推...



我尝试使用 sort() localeCompare(),但如果我有元素'4.5.0''4.11.0',我将它们排序为 ['4.11.0','4.5.0'] ,但我需要 ['4.5.0','4.11.0']



我如何实现这一目标?

解决方案

您可以将所有部分添加到固定大小的字符串中,然后对其进行排序,最后再次删除填充。



< pre class =snippet-code-js lang-js prettyprint-override> var arr = ['5.5.1','4.21.0','4.22.0','6.1.0' ,'5.1.0','4。 5.0']; arr = arr.map(a => a.split('。')。map(n => + n + 100000).join('。'))。sort()。map(a => a.split('。')。map(n => + n-100000).join('。' )); console.log(arr)



显然你必须明智地选择数字100000的大小:它应该至少比你的最大数字部分多一个数字。



使用正则表达式



可以实现相同的操作而无需拆分&当您使用 <的回调参数时加入code>替换 方法:



  var arr = ['5.5.1','4.21.0','4.22.0','6.1.0','5.1.0','4.5.0']; arr = arr.map (a => a.replace(/ \d + / g,n => + n + 100000))。sort()。map(a => a.replace(/ \d + / g,n = > + n-100000)); console.log(arr) 



< h3>仅定义一次填充函数

由于填充及其反向函数非常相似,因此使用一个函数 似乎是一个不错的练习f 两者都有一个额外的参数定义方向(1 =填充,-1 =去填充)。这导致了这个非常模糊和极端的代码。考虑到这只是为了好玩,而不是实际使用:



  var arr = [ '5.5.1','4.21.0','4.22.0','6.1.0','5.1.0','4.5.0']; arr =(f => f(f(arr, 1).sort(), -  1))((arr,v)=> arr.map(a => a.replace(/ \d + / g,n => + n + v * 100000) );; console.log(arr);  



使用 sort 比较回调函数



您可以使用 sort 实现相同目标:

  arr.sort((a,b)=> a.replace(/ \d + / g,n = > + n + 100000)
.localeCompare(b.replace(/ \d + / g,n => + n + 100000)));

但是对于较大的阵列,这会导致性能下降。这是因为排序算法通常需要多次比较某个值,每次都与数组的值不同。这意味着对于相同的数字,必须多次执行填充。因此,较大的数组首先在整个数组中应用填充,然后使用标准排序,然后再次删除填充更快。



但是对于较短的阵列,这种方法可能仍然是最快的。在这种情况下,所谓的自然排序选项 - 可以通过 localeCompare 的额外参数实现 - 将比填充方法:



  var arr = ['5.5.1',' 4.21.0','4.22.0','6.1.0','5.1.0','4.5.0']; arr = arr.sort((a,b)=> a.localeCompare(b, undefined,{numeric:true})); console.log(arr);  



关于填充和一元加的更多信息



要查看填充的工作原理,请查看它生成的中间结果:

  [100005.100005.100001,100004.100021.100000,100004.100022.100000,
100006.100001.100000,100005.100001.100000]

关于表达式 + n + 100000 ,注意第一个 + 一元加号,是将字符串编码的十进制数转换为数字等效数的最有效方法。添加100000以使该数字具有固定的位数。当然,它也可以是200000或300000.请注意,这些添加不会改变数字在数字排序时的顺序。



以上只是填充字符串的一种方法。有关其他替代方案,请参阅此问与答


I have an array of following strings:

['5.5.1', '4.21.0', '4.22.0', '6.1.0', '5.1.0', '4.5.0'] 

...etc.

I need a solution that will give me following ordered result

['4.5.0', '4.21.0', '4.22.0', '5.1.0', '5.5.1', '6.1.0'].

I tried to implement a sort so it first sorts by the numbers in the first position, than in case of equality, sort by the numbers in the second position (after the first dot), and so on...

I tried using sort() and localeCompare(), but if I have elements '4.5.0' and '4.11.0', I get them sorted as ['4.11.0','4.5.0'], but I need to get ['4.5.0','4.11.0'].

How can I achieve this?

解决方案

You could prepend all parts to fixed size strings, then sort that, and finally remove the padding again.

var arr = ['5.5.1', '4.21.0', '4.22.0', '6.1.0', '5.1.0', '4.5.0'];
arr = arr.map( a => a.split('.').map( n => +n+100000 ).join('.') ).sort()
         .map( a => a.split('.').map( n => +n-100000 ).join('.') );

console.log(arr)

Obviously you have to choose the size of the number 100000 wisely: it should have at least one more digit than your largest number part will ever have.

With regular expression

The same manipulation can be achieved without having to split & join, when you use the callback argument to the replace method:

var arr = ['5.5.1', '4.21.0', '4.22.0', '6.1.0', '5.1.0', '4.5.0'];
arr = arr.map( a => a.replace(/\d+/g, n => +n+100000 ) ).sort()
         .map( a => a.replace(/\d+/g, n => +n-100000 ) );

console.log(arr)

Defining the padding function once only

As both the padding and its reverse functions are so similar, it seemed a nice exercise to use one function f for both, with an extra argument defining the "direction" (1=padding, -1=unpadding). This resulted in this quite obscure, and extreme code. Consider this just for fun, not for real use:

var arr = ['5.5.1', '4.21.0', '4.22.0', '6.1.0', '5.1.0', '4.5.0'];
arr = (f=>f(f(arr,1).sort(),-1)) ((arr,v)=>arr.map(a=>a.replace(/\d+/g,n=>+n+v*100000)));

console.log(arr);

Use the sort compare callback function

You could use the compare function argument of sort to achieve the same:

arr.sort( (a, b) => a.replace(/\d+/g, n => +n+100000 )
                     .localeCompare(b.replace(/\d+/g, n => +n+100000 )) );

But for larger arrays this will lead to slower performance. This is because the sorting algorithm will often need to compare a certain value several times, each time with a different value from the array. This means that the padding will have to be executed multiple times for the same number. For this reason, it will be faster for larger arrays to first apply the padding in the whole array, then use the standard sort, and then remove the padding again.

But for shorter arrays, this approach might still be the fastest. In that case, the so-called natural sort option -- that can be achieved with the extra arguments of localeCompare -- will be more efficient than the padding method:

var arr = ['5.5.1', '4.21.0', '4.22.0', '6.1.0', '5.1.0', '4.5.0'];
arr = arr.sort( (a, b) => a.localeCompare(b, undefined, { numeric:true }) );

console.log(arr);

More about the padding and unary plus

To see how the padding works, look at the intermediate result it generates:

[ "100005.100005.100001", "100004.100021.100000", "100004.100022.100000", 
  "100006.100001.100000", "100005.100001.100000" ]

Concerning the expression +n+100000, note that the first + is the unary plus and is the most efficient way to convert a string-encoded decimal number to its numerical equivalent. The 100000 is added to make the number have a fixed number of digits. Of course, it could just as well be 200000 or 300000. Note that this addition does not change the order the numbers will have when they would be sorted numerically.

The above is just one way to pad a string. See this Q&A for some other alternatives.

这篇关于在Javascript中对版本点数字符串进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆