3

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]
];
mrkbtr
  • 453
  • 2
  • 10

2 Answers2

5

Split is the built-in function you need:

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

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

kglr
  • 394,356
  • 18
  • 477
  • 896
2

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] & @ 
  SparseArray[Differences @ a, Automatic, 1]["AdjacencyLists"]

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

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371