Jump to content


[solved] change 1,2,3 to 1-3


  • Please log in to reply
6 replies to this topic

#1 Guests

  • Guests

Posted 07 May 2012 - 05:11 PM

I have a random list of numbers
39,21,25,50,20,35,46,47,23,24,45,22,29

I sort that with
Sort, Num, U N D,

to get 20,21,22,23,24,25,29,35,39,45,46,47,50

My next step is to get that to look like 20-25,29,35,39,45-47,50
Is there an easy way of doing this?

#2 engunneer

engunneer
  • Fellows
  • 9162 posts

Posted 07 May 2012 - 05:36 PM

numberlist = 39,21,25,50,20,35,46,47,23,24,45,22,29

Sort, numberlist, U N D,

previous := -8675309
previous_start := previous
rangelist := ""

Loop, parse, numberlist, `,
{
  current := A_LoopField
  if (current > previous + 1)
  {
    if (previous > previous_start)
      rangelist .= "-" previous "," current   ;more than one member in the range
    else
      rangelist .= "," current                ;only one member in the range
    previous_start := current
  }
  previous := current
}
rangelist := SubStr(rangelist, 2)

msgbox, % rangelist
tested. I got the idea from <!-- m -->http://stackoverflow... ... ng-c-sharp<!-- m --> , but ended up doing it another way.

#3 Guests

  • Guests

Posted 07 May 2012 - 06:09 PM

Thank you so much engunneer! That works like a champ though I still cant understand your code, might take me a little while :?

#4 Guests

  • Guests

Posted 07 May 2012 - 06:46 PM

engunneer

when I try 13,11,10,12,14,20,18,17,19I get
10-14,17
but it should be
10-14,17-20

any idea why?
Thanks for your help

#5 sinkfaze

sinkfaze
  • Moderators
  • 6169 posts

Posted 07 May 2012 - 07:18 PM

Try this one and see if it works:

start := last :=	0, res :=	""
var=13,11,10,12,14,20,18,17,19	[color=#00BF00]; 39,21,25,50,20,35,46,47,23,24,45,22,29[/color]
StringReplace, var, var, `,, `,, UseErrorLevel	[color=#00BF00]; get the number of numbers in the range for later use[/color]
max :=	ErrorLevel + 1
Sort, var, U N D`,
Loop, parse, var, `,	; parse the list of numbers by comman
	if	!last	[color=#00BF00]; if last has not been set yet[/color]
		res .=	A_LoopField, start := last :=	A_LoopField	[color=#00BF00]; add the current number to our final variable and set 'start' and 'last' to the current number[/color]
	else if	(A_LoopField=last+1)	[color=#00BF00]; if the current number is consecutive to the last number[/color]
		if	(A_Index=max)	[color=#00BF00]; and if the current number is the last in the series[/color]
			res .=	"-" A_LoopField	[color=#00BF00]; close the range in our final variable[/color]
		else	last :=	A_LoopField	[color=#00BF00]; else increment the 'last' variable[/color]
	else if	(last - start >= 1)	[color=#00BF00]; else if the current number is not consecutive to the last number and the difference between 'start' and 'last' is greater than or equal to 1 (thus indicating a range)[/color]
		res .=	"-" last "," A_LoopField, start := last :=	A_LoopField	[color=#00BF00]; close the range, add the comma-separated current number to our final variable, and set 'start' and 'last' to the current number[/color]
	else	res .=	"," A_LoopField, start := last :=	A_LoopField	[color=#00BF00] ; else just add the comma-separated current number to our final variable, and set 'start' and 'last' to the current number[/color]
MsgBox %	res
return


#6 rbrtryn

rbrtryn
  • Members
  • 927 posts

Posted 07 May 2012 - 07:19 PM

Try this one. It probably could be more efficient, but it does work for both the number lists you provided>
#NoEnv
#SingleInstance force

List := "13,11,10,12,14,20,18,17,19"

Sort List, U N D,

Result :=""
PriorNum :=""

Loop Parse, List, `,
{
    if (PriorNum = "") {
        PriorNum := A_LoopField
        RangeStart := A_LoopField
        RangeEnd := ""
        continue
    }
    
    if (PriorNum + 1 = A_LoopField) {
        RangeEnd := A_LoopField
    }
    else {
        Result .= (Result <> "") ? "," : ""
        Result .= RangeStart
        if (RangeEnd <> "") {
            Result .= RangeEnd - RangeStart > 1 ? "-" : ","
            Result .= RangeEnd
        }
        RangeStart := A_LoopField
        RangeEnd := ""
    }
    PriorNum := A_LoopField
}

; Clean up the end condition
Result .= (Result <> "") ? "," : ""
Result .= RangeStart
if (RangeEnd <> "") {
    Result .= RangeEnd - RangeStart > 1 ? "-" : ","
    Result .= RangeEnd
}
MsgBox %Result%


#7 Guests

  • Guests

Posted 07 May 2012 - 08:53 PM

Thank you all(engunneer,sinkfaze,rbrtryn) for your help on this. I have a better understanding of how it works now and got it working. Thank you again.