如何将数组中的连续整数减少为连字符范围表达式?
在 JavaScript 中,如何将数组中的数字序列转换为数字范围?换句话说,我想将连续出现的整数(无间隙)表示为连字符范围。
[2,3,4,5,10,18,19,20]
将变为 [2-5,10,18-20]
[1, 6,7,9,10,12]
将变为 [1,6-7,9-10,12]
[3,5,99]
仍将是 [3,5,99]
[5,6,7,8,9,10,11]
将变为 [5-11]
In JavaScript, how can I convert a sequence of numbers in an array to a range of numbers? In other words, I want to express consecutive occurring integers (no gaps) as hyphenated ranges.
[2,3,4,5,10,18,19,20]
would become [2-5,10,18-20]
[1,6,7,9,10,12]
would become [1,6-7,9-10,12]
[3,5,99]
would remain [3,5,99]
[5,6,7,8,9,10,11]
would become [5-11]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
这是我不久前制作的一个算法,最初是为 C# 编写的,现在我将它移植到 JavaScript 中:
Here is an algorithm that I made some time ago, originally written for C#, now I ported it to JavaScript:
只是享受 CMS 的解决方案的乐趣:
Just having fun with solution from CMS :
非常好的问题:这是我的尝试:
JSFiddler 上的演示
Very nice question: here's my attempt:
Demo on JSFiddler
今天,我需要 TypeScript 代码来解决这个问题(OP 发布多年后),并决定尝试使用比此处其他答案更实用的风格编写的版本。当然,只有参数和返回类型注释将此代码与标准 ES6 JavaScript 区分开来。
请注意,
slice
是必需的,因为sort
就地排序,我们无法更改原始数组。I needed TypeScript code today to solve this very problem -- many years after the OP -- and decided to try a version written in a style more functional than the other answers here. Of course, only the parameter and return type annotations distinguish this code from standard ES6 JavaScript.
Note that
slice
is necessary becausesort
sorts in place and we can't change the original array.这是我对此的看法......
Here's my take on this...
使用 ES6,解决方案是:
如果您想添加额外的空格以提高可读性,只需添加对
string.prototype.replace()
的额外调用即可。如果输入向量未排序,您可以在
display()
函数的左大括号后面添加以下行:vector.sort ( ( a, b ) => a - b); // 按升序对向量进行适当排序
。请注意,这可以改进以避免对整数相邻性进行两次测试(相邻性?我不是以英语为母语的人;-)。
当然,如果您不想输出单个字符串,请用“;”将其分隔。
Using ES6, a solution is:
If you want to add extra spaces for readability, just add extra calls to
string.prototype.replace()
.If the input vector is not sorted, you can add the following line right after the opening brace of the
display()
function:vector.sort ( ( a, b ) => a - b ); // sort vector in place, in increasing order
.Note that this could be improved to avoid testing twice for integer adjacentness (adjacenthood? I'm not a native English speaker;-).
And of course, if you don't want a single string as output, split it with ";".
该过程的大致轮廓如下:
ranges
的空数组值
ranges
为空,则插入项目{min: value, max: value}
范围
中最后一项的max
与当前值
连续,则设置最后一项的max
范围
中的项目=值
{min: value, max: value}
ranges
数组,例如通过组合min
和max
if same下面的代码使用 Array.reduce 并结合步骤 2.1 和 2.3 简化了逻辑。
Rough outline of the process is as follows:
ranges
value
in sorted input arrayranges
is empty then insert the item{min: value, max: value}
max
of last item inranges
and the currentvalue
are consecutive then setmax
of last item inranges
=value
{min: value, max: value}
ranges
array as desired e.g. by combiningmin
andmax
if sameThe following code uses
Array.reduce
and simplifies the logic by combining step 2.1 and 2.3.如果您只需要一个表示范围的字符串,那么您将找到序列的中点,这将成为您的中间值(在示例中为 10)。然后,您将抓取序列中的第一个项目以及紧邻中点之前的项目,并构建第一个序列表示。您将遵循相同的过程来获取最后一个项目以及紧随中点之后的项目,并构建最后一个序列表示。
在线演示:http://jsbin.com/uvahi/edit
If you simply want a string that represents a range, then you'd find the mid-point of your sequence, and that becomes your middle value (10 in your example). You'd then grab the first item in the sequence, and the item that immediately preceded your mid-point, and build your first-sequence representation. You'd follow the same procedure to get your last item, and the item that immediately follows your mid-point, and build your last-sequence representation.
Demo Online: http://jsbin.com/uvahi/edit
类似的事情。
Something like that.
改编自 CMS 的 javascript 解决方案,用于 Cold Fusion
它首先对列表进行排序,以便
1,3,2, 4,5,8,9,10
(或类似)正确转换为1-5,8-10
。An adaptation of CMS's javascript solution for Cold Fusion
It does sort the list first so that
1,3,2,4,5,8,9,10
(or similar) properly converts to1-5,8-10
.为你们准备的微型 ES6 模块。它接受一个函数来确定何时必须中断序列(breakDetectorFunc 参数 - 默认值对于整数序列输入来说很简单)。
注意:由于输入是抽象的 - 在处理之前没有自动排序,因此如果您的序列未排序 - 在调用此模块之前执行此操作
第一个参数是输入序列排序数组,第二个参数是控制输出模式的布尔标志:如果为 true - 单个项目(在间隔之外)将作为数组返回:[1,7]、[9,9]、[10,10]、[12,20],否则返回单个项目,因为它们出现在 输入数组:
示例输入的
它将返回
Tiny ES6 module for you guys. It accepts a function to determine when we must break the sequence (breakDetectorFunc param - default is the simple thing for integer sequence input).
NOTICE: since input is abstract - there's no auto-sorting before processing, so if your sequence isn't sorted - do it prior to calling this module
first argument is the input sequence sorted array, second is a boolean flag controlling the output mode: if true - single item (outside the intervals) will be returned as arrays anyway: [1,7],[9,9],[10,10],[12,20], otherwise single items returned as they appear in the input array
for your sample input
it will return:
这是 Coffeescript 中的一个版本
Here's a version in Coffeescript
我已经编写了自己的方法,该方法依赖于 Lo-Dash,但不仅仅返回一个范围数组,而是仅返回一个范围组数组。
[1,2,3,4,6,8,10] 变为:
http://jsfiddle.net/mberkom /ufVey/
I've written my own method that's dependent on Lo-Dash, but doesn't just give you back an array of ranges, rather, it just returns an array of range groups.
[1,2,3,4,6,8,10] becomes:
http://jsfiddle.net/mberkom/ufVey/