Function Repository Resource:

SplitByIndexed

Source Notebook

A function like SplitBy, but with added support for using the indices of the elements in the list

Contributed by: Sjoerd Smit

ResourceFunction["SplitByIndexed"][list,f]

splits list into sublists consisting of runs of successive elements that give the same value when the function f is applied to the element and index.

ResourceFunction["SplitByIndexed"][list,{f1,f2,}]

recursively splits list into sublists by testing elements successively with each of the fi.

ResourceFunction["SplitByIndexed"][f]

represents an operator form of ResourceFunction["SplitByIndexed"] that can be applied to expressions.

Details

ResourceFunction["SplitByIndexed"] extends SplitBy in a way similar to the way MapIndexed extends Map. However, since SplitBy does not have level specifications, the position is passed to the function as an integer instead of as a list.
In ResourceFunction["SplitByIndexed"], f[val, index] is a two argument funtion where the first argument corresponds to the element and the second argument corresponds to the position in the list.
Unlike SplitBy, ResourceFunction["SplitByIndexed"] applies f exactly once for each element.

Examples

Basic Examples (3) 

Split the list into runs of length up to 3:

In[1]:=
ResourceFunction["SplitByIndexed"][{a, b, c, d, e, f, g}, Quotient[#2, 3, 1] &]
Out[1]=

Single out the elements at positions that are a multiple of 4:

In[2]:=
ResourceFunction["SplitByIndexed"][{a, b, c, d, e, f, g}, Mod[#2, 4] == 0 &]
Out[2]=

Split based on both the value and position in the list:

In[3]:=
ResourceFunction["SplitByIndexed"][Reverse@Range[20], Function[{element, index}, PrimeQ[element] || PrimeQ[index]]]
Out[3]=

This might clarify:

In[4]:=
SplitBy[Table[{21 - n, PrimeQ[21 - n] || PrimeQ[n], n}, {n, 1, 20}], #[[2]] &]
Out[4]=

Scope (1) 

Specify a second splitting function to partition the sublists into runs of length up to 2:

In[5]:=
ResourceFunction["SplitByIndexed"][
 Reverse@Range[20], {PrimeQ[#1] &, Quotient[#2, 2, 1] &}]
Out[5]=

Properties and Relations (3) 

SplitByIndexed can be used in the same way as SplitBy if you restrict the function to only the first argument:

In[6]:=
ResourceFunction["SplitByIndexed"][Tuples[{1, 2}, 3], First[#1] &]
Out[6]=
In[7]:=
SplitBy[Tuples[{1, 2}, 3], First]
Out[7]=

However, SplitByIndexed will evaluate the test function only exactly once for each element:

In[8]:=
Reap@ResourceFunction["SplitByIndexed"][Range[10], PrimeQ[Sow[#]] &]
Out[8]=

SplitBy evaluates the test function twice for all elements except the first and last:

In[9]:=
Reap@SplitBy[Range[10], PrimeQ[Sow[#]] &]
Out[9]=

Publisher

Sjoerd Smit

Requirements

Wolfram Language 13.0 (December 2021) or above

Version History

  • 1.0.1 – 23 August 2023
  • 1.0.0 – 21 August 2023

Related Resources

License Information