Skip to main content
added 373 characters in body
Source Link
Stéphane Chazelas
  • 586.7k
  • 96
  • 1.1k
  • 1.7k

With zsh instead, you could define a function like:

reduce() { local i=1 argv=(${(nus:,:)1}) # split $1 on ",", numerically sort and remove dups while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { ((i++)) } } print ${(j:,:)@} } 

Which would also accept ranges on input:

$ reduce 1,2,3,5,6,7,8,9,12,14 1-3,5-9,12,14 $ reduce 1,2,3,5-7,8,9-11,12,13-20 1-3,5-20 $ reduce 5,2,4,5,6 2,4-6 

Note that it won't work properly if the input has overlapping ranges:

$ reduce 1-3,2 1-3,2 $ reduce 1-3,2-4 1-3,2-4 

From bash, you'd define the function as:

reduce() { zsh -c ' i=1 argv=(${(nus:,:)1}) # split $1 on ",", numerically sort and remove dups while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { ((i++)) } } print ${(j:,:)@}' zsh "$@" } 

With zsh instead, you could define a function like:

reduce() { local i=1 argv=(${(nus:,:)1}) # split $1 on ",", numerically sort and remove dups while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { ((i++)) } } print ${(j:,:)@} } 

Which would also accept ranges on input:

$ reduce 1,2,3,5,6,7,8,9,12,14 1-3,5-9,12,14 $ reduce 1,2,3,5-7,8,9-11,12,13-20 1-3,5-20 $ reduce 5,2,4,5,6 2,4-6 

Note that it won't work properly if the input has overlapping ranges:

$ reduce 1-3,2 1-3,2 $ reduce 1-3,2-4 1-3,2-4 

With zsh instead, you could define a function like:

reduce() { local i=1 argv=(${(nus:,:)1}) # split $1 on ",", numerically sort and remove dups while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { ((i++)) } } print ${(j:,:)@} } 

Which would also accept ranges on input:

$ reduce 1,2,3,5,6,7,8,9,12,14 1-3,5-9,12,14 $ reduce 1,2,3,5-7,8,9-11,12,13-20 1-3,5-20 $ reduce 5,2,4,5,6 2,4-6 

Note that it won't work properly if the input has overlapping ranges:

$ reduce 1-3,2 1-3,2 $ reduce 1-3,2-4 1-3,2-4 

From bash, you'd define the function as:

reduce() { zsh -c ' i=1 argv=(${(nus:,:)1}) # split $1 on ",", numerically sort and remove dups while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { ((i++)) } } print ${(j:,:)@}' zsh "$@" } 
added 214 characters in body
Source Link
Stéphane Chazelas
  • 586.7k
  • 96
  • 1.1k
  • 1.7k

With zsh instead, you could define a function like:

reduce() { local i=1 argv=(${(snus:,:)1}) # split $1 on ",", numerically sort and remove dups while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { (( i++ )) } } print ${(j:,:)@} } 

Which would also accept ranges on input:

$ reduce 1,2,3,5,6,7,8,9,12,14 1-3,5-9,12,14 $ reduce 1,2,3,5-7,8,9-11,12,13-20 1-3,5-20 $ reduce 5,2,4,5,6 2,4-6 

Note that it won't work properly if the input has overlapping ranges:

$ reduce 1-3,2 1-3,2 $ reduce 1-3,2-4 1-3,2-4 

With zsh instead, you could define a function like:

reduce() { local i=1 argv=(${(s:,:)1}) while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { (( i++ )) } } print ${(j:,:)@} } 

Which would also accept ranges on input:

$ reduce 1,2,3,5,6,7,8,9,12,14 1-3,5-9,12,14 $ reduce 1,2,3,5-7,8,9-11,12,13-20 1-3,5-20 

With zsh instead, you could define a function like:

reduce() { local i=1 argv=(${(nus:,:)1}) # split $1 on ",", numerically sort and remove dups while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { ((i++)) } } print ${(j:,:)@} } 

Which would also accept ranges on input:

$ reduce 1,2,3,5,6,7,8,9,12,14 1-3,5-9,12,14 $ reduce 1,2,3,5-7,8,9-11,12,13-20 1-3,5-20 $ reduce 5,2,4,5,6 2,4-6 

Note that it won't work properly if the input has overlapping ranges:

$ reduce 1-3,2 1-3,2 $ reduce 1-3,2-4 1-3,2-4 
Source Link
Stéphane Chazelas
  • 586.7k
  • 96
  • 1.1k
  • 1.7k

With zsh instead, you could define a function like:

reduce() { local i=1 argv=(${(s:,:)1}) while ((i < $#)) { if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) { argv[i]=${argv[i]%-*}-${argv[i+1]#*-} argv[i+1]=() } else { (( i++ )) } } print ${(j:,:)@} } 

Which would also accept ranges on input:

$ reduce 1,2,3,5,6,7,8,9,12,14 1-3,5-9,12,14 $ reduce 1,2,3,5-7,8,9-11,12,13-20 1-3,5-20