# Subgrouping elements of list based on their values

In a list of elements I want to group the elements which are in consecutive order. For eg.

list = {2,3,4,5,6,9,12,13,14,16,17}
result = {{2,3,4,5,6},{9},{12,13,14},{16,17}}


I have written the code below for it and it works fine. I wanted to know if I can use any in built Function to do it in a better way.

 For[
i = 1; res = {},
i <=   Length[list],
i++,
temp = {list[[i]]} ; While[If[i + 1 > Length[list], Break[]];list[[i + 1]] - list[[i]] == 1,AppendTo[temp, list[[i + 1]]]; i++]; AppendTo[res, temp]
];

• – kglr
Jul 4, 2017 at 15:10

Split is the built-in function you need:

Split[list, #2 == # + 1 &]


{{2, 3, 4, 5, 6}, {9}, {12, 13, 14}, {16, 17}}

• Looks neat. Thanks. Jul 4, 2017 at 15:12
• @mrkbtr, my pleasure. Thank you for the accept.
– kglr
Jul 4, 2017 at 15:13
• kglr, I think this question reasonably already has an answer in (23607); do you disagree? Jul 5, 2017 at 15:38
• @Mr.Wizard, the linked question(s) asks more than what Split gives. One of the answers does use Split as a step, but imho it would be difficult for an average user to use that answer to identify an answer for the current question.
– kglr
Jul 5, 2017 at 19:15

This question is arguably answered in Find subsequences of consecutive integers inside a list.

Nevertheless as it remains open it is beneficial to apply similar methods here.

Using intervals from my answer there this is solved with:

Range @@@ intervals[list]

{{2, 3, 4, 5, 6}, {9}, {12, 13, 14}, {16, 17}}


This can be much faster than Split:

intervals[a_List] :=
{a[[Prepend[# + 1, 1]]], a[[Append[#, -1]]]}\[Transpose] & @

a = Delete[#, List /@ RandomSample[#, 15000]] &@Range@1*^7;

(r1 = Range @@@ intervals[a])  // RepeatedTiming // First

(r2 = Split[a, #2 == # + 1 &]) // RepeatedTiming // First

r1 === r2

0.13

6.20

True