Function Repository Resource:

SpanRange

Source Notebook

Construct an explicit position range from a span specification

Contributed by: Nikolay Murzin

ResourceFunction["SpanRange"][span,len]

returns arguments for a Range representing span over an expression of length len.

ResourceFunction["SpanRange"][span, expr]

derives the length from a given expression expr.

Details

span is a Span taking a general form of min;;max;;step.
Any argument of span (min, max or step) can be All, in which case it is interpreted as returning the largest possible number of elements consistent with any possible value of that argument.
The first two integers of a span are considered ordinals indexing parts of an expression with a given length, with 0 pointing to the Head of an expression and negative integers indexing from the end.
Span specifications of the form min;;UpTo[n] and UpTo[n];;max will result in a range with a maximum of n elements (n is treated as a cardinal).
UpTo[n];;UpTo[m] will result in a range with a maximum of Min[n,m] elements.
UpTo[Infinity] is the same as All.
Some spans including 0 are invalid when used as a Part specification but are still supported in ResourceFunction["SpanRange"].

Examples

Basic Examples (2) 

Get a range from a span specification:

In[1]:=
ResourceFunction["SpanRange"][3 ;; 7, 10]
Out[1]=
In[2]:=
Range @@ %
Out[2]=

Get another range from span specification:

In[3]:=
ResourceFunction["SpanRange"][2 ;; 9 ;; 2, 10]
Out[3]=
In[4]:=
Range @@ %
Out[4]=

Scope (9) 

Negative integers:

In[5]:=
ResourceFunction["SpanRange"][3 ;; -3, 10]
Out[5]=
In[6]:=
ResourceFunction["SpanRange"][-7 ;; 7, 10]
Out[6]=
In[7]:=
ResourceFunction["SpanRange"][-6 ;; -2, 10]
Out[7]=

Negative step:

In[8]:=
ResourceFunction["SpanRange"][7 ;; 3 ;; -1, 10]
Out[8]=
In[9]:=
ResourceFunction["SpanRange"][9 ;; 2 ;; -2, 10]
Out[9]=

Use of All for the min and max:

In[10]:=
ResourceFunction["SpanRange"][All ;; 3, 10]
Out[10]=
In[11]:=
ResourceFunction["SpanRange"][All ;; 3 ;; -1, 10]
Out[11]=
In[12]:=
ResourceFunction["SpanRange"][3 ;; All, 10]
Out[12]=
In[13]:=
ResourceFunction["SpanRange"][3 ;; All ;; -1, 10]
Out[13]=

Use of All for the step:

In[14]:=
ResourceFunction["SpanRange"][3 ;; 7 ;; All, 10]
Out[14]=
In[15]:=
ResourceFunction["SpanRange"][7 ;; 3 ;; All, 10]
Out[15]=
In[16]:=
ResourceFunction["SpanRange"][All ;; 7 ;; All, 10]
Out[16]=
In[17]:=
ResourceFunction["SpanRange"][All ;; 3 ;; All, 10]
Out[17]=
In[18]:=
ResourceFunction["SpanRange"][10 ;; All ;; All, 10]
Out[18]=

Use of single UpTo:

In[19]:=
ResourceFunction["SpanRange"][4 ;; UpTo[3], 10]
Out[19]=
In[20]:=
ResourceFunction["SpanRange"][UpTo[3] ;; 2 ;; All, 10]
Out[20]=
In[21]:=
ResourceFunction["SpanRange"][All ;; UpTo[3], 10]
Out[21]=
In[22]:=
ResourceFunction["SpanRange"][UpTo[3] ;; All ;; All, 10]
Out[22]=
In[23]:=
ResourceFunction["SpanRange"][4 ;; UpTo[10] ;; All, 10]
Out[23]=
In[24]:=
ResourceFunction["SpanRange"][6 ;; UpTo[10] ;; All, 10]
Out[24]=
In[25]:=
ResourceFunction["SpanRange"][UpTo[4] ;; 6 ;; All, 10]
Out[25]=
In[26]:=
ResourceFunction["SpanRange"][UpTo[10] ;; 4 ;; All, 10]
Out[26]=

UpTo[0] generates different empty ranges:

In[27]:=
ResourceFunction["SpanRange"][UpTo[0] ;; ;; 1, 10]
Out[27]=
In[28]:=
ResourceFunction["SpanRange"][UpTo[0] ;; ;; -1, 10]
Out[28]=
In[29]:=
ResourceFunction["SpanRange"][;; UpTo[0] ;; 1, 10]
Out[29]=
In[30]:=
ResourceFunction["SpanRange"][;; UpTo[0] ;; -1, 10]
Out[30]=

0 is allowed as the min or the max (which is indexing the Head of an expression):

In[31]:=
ResourceFunction["SpanRange"][0 ;;, 10]
Out[31]=
In[32]:=
ResourceFunction["SpanRange"][-1 ;; 0 ;; -1, 10]
Out[32]=
In[33]:=
ResourceFunction["SpanRange"][0 ;; 0, 10]
Out[33]=

UpTo[Infinity] is the same as All:

In[34]:=
ResourceFunction["SpanRange"][UpTo[Infinity] ;; 4 ;; All, 10]
Out[34]=
In[35]:=
ResourceFunction["SpanRange"][4 ;; UpTo[Infinity] ;; All, 10]
Out[35]=

Use UpTo at both ends of the span:

In[36]:=
ResourceFunction["SpanRange"][UpTo[7] ;; UpTo[3], 10]
Out[36]=
In[37]:=
ResourceFunction["SpanRange"][UpTo[3] ;; UpTo[7] ;; All, 10]
Out[37]=
In[38]:=
ResourceFunction["SpanRange"][UpTo[3] ;; UpTo[7] ;; 1, 10]
Out[38]=
In[39]:=
ResourceFunction["SpanRange"][UpTo[3] ;; UpTo[7] ;; -1, 10]
Out[39]=

Applications (1) 

Use SpanRange with Range to generate explicit part numbers for various computations:

In[40]:=
extract[expr_, span_Span] := Enclose@Extract[expr, List /@ Range @@ Confirm@ResourceFunction["SpanRange"][span, expr]]
In[41]:=
mapAt[f_, expr_, span_Span] := Enclose@MapAt[f, expr, List /@ Range @@ Confirm@ResourceFunction["SpanRange"][span, expr]]
In[42]:=
replacePart[expr_, span_Span -> new_] := Enclose@ReplacePart[expr, new, List /@ Range @@ Confirm@ResourceFunction["SpanRange"][span, expr]]
In[43]:=
extract[{1, 2, 3, 4}, -2 ;;]
Out[43]=
In[44]:=
extract[{1, 2, 3, 4}, -2 ;; 0 ;; -1]
Out[44]=
In[45]:=
mapAt[f, {1, 2, 3, 4}, 2 ;; UpTo[2]]
Out[45]=
In[46]:=
mapAt[f, {1, 2, 3, 4}, -2 ;; UpTo[2] ;; -2]
Out[46]=
In[47]:=
mapAt[f, {1, 2, 3, 4}, 2 ;; 0 ;; All]
Out[47]=
In[48]:=
replacePart[{1, 2, 3, 4}, 0 ;; UpTo[2] -> x]
Out[48]=
In[49]:=
replacePart[{1, 2, 3, 4}, ;; ;; 2 -> x]
Out[49]=

Possible Issues (1) 

Invalid spans indexing beyond a given length result in Failure:

In[50]:=
ResourceFunction["SpanRange"][3 ;; 15, 10]
Out[50]=
In[51]:=
ResourceFunction["SpanRange"][15 ;; 1 ;; All, 10]
Out[51]=
In[52]:=
ResourceFunction["SpanRange"][-15 ;;, 10]
Out[52]=
In[53]:=
ResourceFunction["SpanRange"][;; -15, 10]
Out[53]=

Requirements

Wolfram Language 13.0 (December 2021) or above

Version History

  • 1.3.0 – 08 March 2024
  • 1.2.0 – 27 September 2023
  • 1.1.0 – 10 May 2022
  • 1.0.0 – 18 April 2022

License Information