8

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

Kuba
  • 136,707
  • 13
  • 279
  • 740
ZaMoC
  • 6,697
  • 11
  • 31

3 Answers3

10

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}}
Kuba
  • 136,707
  • 13
  • 279
  • 740
10
Select[Split[list, #2 - #1 == 1 &], Length[#] > 1 &]

Also can get the same result

yode
  • 26,686
  • 4
  • 62
  • 167
  • 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. – EGME Oct 11 '19 at 12:21
  • Ok, I figured out how to do this, you just set Length[#]>=1& ... – EGME Oct 11 '19 at 13:41
3

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.)

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