8
$\begingroup$

I have a list

  list={3, 4, 8, 1, 2, 5, 6, 7, 9}

and I want to find all the ordered subsequences of consecutive integers

in my example I should get

 {{3, 4}, {1, 2}, {5, 6, 7}}

as you can see {5,6}, {6,7} must NOT be included in the final result

$\endgroup$
1
  • $\begingroup$ closely related: 23607 $\endgroup$
    – Kuba
    Mar 19, 2017 at 20:54

3 Answers 3

10
$\begingroup$

Didn't find an exact duplicate so let's use another closely related:

How to detect if a sequence of integers is consecutive, credits to Simon Woods

consecutiveQ = Most[#] == Rest[#] - 1 &

SequenceCases[{3, 4, 8, 1, 2, 5, 6, 7, 9}, {_, __}?consecutiveQ]
{{3, 4}, {1, 2}, {5, 6, 7}}
$\endgroup$
3
  • $\begingroup$ thanx.it works! and it's elegant $\endgroup$
    – ZaMoC
    Mar 19, 2017 at 21:11
  • $\begingroup$ @Jenny Elegant, but unfortunately extremely slow on long lists. Please see my answer for a comparison. (My apologies Kuba for "attacking" your method.) $\endgroup$
    – Mr.Wizard
    Jul 6, 2017 at 7:05
  • $\begingroup$ @Mr.Wizard always feel free to do so as almost always I ignore performance in my answers. $\endgroup$
    – Kuba
    Jul 6, 2017 at 7:12
10
$\begingroup$
Select[Split[list, #2 - #1 == 1 &], Length[#] > 1 &]

Also can get the same result

$\endgroup$
2
  • $\begingroup$ Can you modify this so that if you have a list like {1,2,3,5,7,8,9} you will get back {{1,2,3},{5},{7,8,9}} instead of {{1,2,3},{7,8,9}} ???? I am tempted to post the question but I thought I would ask first. $\endgroup$
    – EGME
    Oct 11, 2019 at 12:21
  • $\begingroup$ Ok, I figured out how to do this, you just set Length[#]>=1& ... $\endgroup$
    – EGME
    Oct 11, 2019 at 13:41
3
$\begingroup$

Based on intervals from Find subsequences of consecutive integers inside a list:

consec[a_List] :=
  SparseArray[Differences@a, Automatic, 1]["AdjacencyLists"] //
    {a[[Prepend[# + 1, 1]]], a[[Append[#, -1]]]} & //
      Range @@@ Pick[#\[Transpose], Unitize[Subtract @@ #], 1] &

consec[{3, 4, 8, 1, 2, 5, 6, 7, 9}]
{{3, 4}, {1, 2}, {5, 6, 7}}

Benchmark including the two existing answers as fnK and fnY:

consecutiveQ = Most[#] == Rest[#] - 1 &;

fnK[lst_] := SequenceCases[lst, {_, __}?consecutiveQ]
fnY[lst_] := Select[Split[lst, #2 - #1 == 1 &], Length[#] > 1 &]

Needs["GeneralUtilities`"]

BenchmarkPlot[{fnK, fnY, consec}, RandomInteger[9, #] &, 2]

enter image description here

(Note the log-log scale.)

$\endgroup$

Your Answer

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

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