3
$\begingroup$

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]
];
$\endgroup$
1

2 Answers 2

5
$\begingroup$

Split is the built-in function you need:

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

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

$\endgroup$
4
  • $\begingroup$ Looks neat. Thanks. $\endgroup$
    – mrkbtr
    Commented Jul 4, 2017 at 15:12
  • $\begingroup$ @mrkbtr, my pleasure. Thank you for the accept. $\endgroup$
    – kglr
    Commented Jul 4, 2017 at 15:13
  • $\begingroup$ kglr, I think this question reasonably already has an answer in (23607); do you disagree? $\endgroup$
    – Mr.Wizard
    Commented Jul 5, 2017 at 15:38
  • 1
    $\begingroup$ @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. $\endgroup$
    – kglr
    Commented Jul 5, 2017 at 19:15
2
$\begingroup$

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
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.