3

I am generating data such as {4,5,6,7,8,9,20,21,22,23,24,25,78,79,90}. This list can reach thousands of elements. Is there a simple or good method to convert such a list into a set on Interval objects which would be much shorter and manageable.

Thanks

Lorenz H Menke
  • 269
  • 1
  • 8
  • What is an interval object? – Igor Rivin Apr 08 '17 at 00:20
  • Mathematica has the function Interval[1,5] which is equivalent to {1,2,3,4,5} – Lorenz H Menke Apr 08 '17 at 00:25
  • According to the documentation it is NOT equivalent to that, but, rather, is the closed interval from $1$ to $5,$ so my question stands. Intervals do not appear to be the same as ranges... – Igor Rivin Apr 08 '17 at 00:28
  • Well yes they are not equivalent but the answer that I am looking for would from the example {Interval[4,9],Interval[20,25],Interval[78,79],Interval[90,90]}. I am not for this case interested in interval arithmetic just a representation. For the cases where there are thousands of elements the number of intervals would be about 10-20 which i much easier to analyze for my purpose. – Lorenz H Menke Apr 08 '17 at 00:39

3 Answers3

2

how about this?

S = {4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 78, 79, 90};
consec = Most[#] == Rest[#] - 1 &;
DS = SequenceCases[S, {_, __}?consec];
Table[{First@DS[[i]], Last@DS[[i]]}, {i, 1, Length@DS}]

this one is better

S = {4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 78, 79, 90};
{Min[#], Max[#]} & /@ Split[S, #2 - #1 == 1 &]
ZaMoC
  • 6,697
  • 11
  • 31
0

Well, here is the simplest I can think of:

foo[l_, x_] := Module[{ll = l[[-1, -1]]},
  If[ll + 1 == x, Append[l[[;; -2]], Append[l[[-1]], x]],
   Append[l, {x}]]]

z[l_] := Fold[foo, {{l[[1]]}}, Rest[l]]

makeInt[l_] := int[#[[1]], #[[-1]]] & /@ z[l]

(notice that I am not using Interval, to avoid confusion.

Igor Rivin
  • 5,094
  • 20
  • 19
0

You may use methods from Find continuous sequences inside a list, i.e. my intervals:

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

intervals[{4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 78, 79, 90}]

Interval @@ %

NumberLinePlot[%]
{{4, 9}, {20, 25}, {78, 79}, {90, 90}}

Interval[{4, 9}, {20, 25}, {78, 79}, {90, 90}]

enter image description here

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